Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 17, 2021 09:17 pm GMT

Create your first RESTful API with Deno, Oak and MongoDB

In this article we are going to create a RESTful API with CRUD functionalities. We're going to talk about Deno in detail and build a server using Oak, which is a minimalistic middleware framework (similar to Express).

Prerequisites

At least some basic knowledge of these technologies / concepts is required.

  • ES6 Features
  • TypeScript
  • RESTful APIs
  • MongoDB

What is Deno?

Similar to Node.js, Deno is a JavaScript / TypeScript runtime based on the V8 JavaScript Engine. It was created by Ryan Dahl (also the creator of Node.js).

Why should we use Deno?

  • Built-in support for TypeScript
  • Runs in a sandbox and is secure by default
  • De-centralized packages
  • ES Modules
  • Top Level Await

Installation

Using Shell (macOS and Linux):
curl -fsSL https://deno.land/x/install/install.sh | sh

Using PowerShell (Windows):
iwr https://deno.land/x/install/install.ps1 -useb | iex

For more installation options checkout the documentation

To test your installation, run deno --version. If this prints the Deno version to the console the installation was successful.

Let's start building

We are going to create a quotes API which will provide us endpoints to perform CRUD operations on these quotes.

Create a server.ts and bring in Application from Oak. Now create a new Application

import { Application } from "https://deno.land/x/oak/mod.ts";const app = new Application();

Now start the server with

const PORT = 4000;await app.listen({ port: PORT });console.log(`Server running on PORT: ${PORT}`)

We will keep our code clean and separated in modules. Let's make a routes.ts file to define our routes. We will come back to the server.ts file soon. In the routes.ts file - Bring in Router from Oak

import { Router } from "https://deno.land/x/oak/mod.ts";const router = new Router(); // Create Routerrouter  .get("/api/quote", getQuotes) // Get all quotes  .get("/api/quote/:id", getQuote) // Get one quote of quoteID: id  .post("/api/quote", addQuote) // Add a quote  .put("/api/quote/:id", updateQuote) // Update a quote  .delete("/api/quote/:id", deleteQuote); // Delete a quoteexport default router;

At this point, these functions passed in the routes will be undefined, we'll come back to that later. First, let's import our router in the server.ts file.

import router from "./routes.ts"; // Bringing in routerapp.use(router.routes()); // Pass our router as a middlewareapp.use(router.allowedMethods()); // Allow HTTP methods on router

Our server.ts should look like this

import { Application } from "https://deno.land/x/oak/mod.ts";import router from "./routes.ts";const PORT = 4000;const app = new Application();app.use(router.routes());app.use(router.allowedMethods());await app.listen({ port: PORT });console.log(`Server listening on ${PORT}`);

Now, let's build our controllers. Create a controllers directory in the root of your project. Then create controllers.js -

First, create an interface for a quote

interface Quote {  _id: { $oid: string };  quote: string;  quoteID: string;  author: string;}

Next, we'll bring in MongoClient from Deno's Mongo Library in our controllers.ts and try to connect with it. Make sure you have a MongoDB Local instance running. You can also use MongoDB Atlas, just replace your URI with the one here.

import { MongoClient } from "https://deno.land/x/[email protected]/mod.ts";const URI = "mongodb://127.0.0.1:27017";// Mongo Connection Initconst client = new MongoClient();try {  await client.connect(URI);  console.log("Database successfully connected");} catch (err) {  console.log(err);}const db = client.database("quotesApp"); const quotes = db.collection<Quote>("quotes");

Let's get to the fun part now, we'll create our first controller - addQuote to add a quote to the database.

// DESC: ADD single quote// METHOD: POST /api/quoteconst addQuote = async ({  request,  response,}: {  request: any;  response: any;}) => {  try {    // If the request has no Body, it will return a 404    if (!request.hasBody) {       response.status = 400;      response.body = {        success: false,        msg: "No Data",      };    } else {      // Otherwise, it will try to insert       // a quote in the DB and respond with 201      const body = await request.body();      const quote = await body.value;      await quotes.insertOne(quote);      response.status = 201;      response.body = {        success: true,        data: quote,      };    }  } catch (err) {    response.body = {      success: false,      msg: err.toString(),    };  }};

Next, we move on to the getQuote function which returns a quote from the database.

// DESC: GET single quote// METHOD: GET /api/quote/:idconst getQuote = async ({  params,  response,}: {  params: { id: string };  response: any;}) => {  // Searches for a particular quote in the DB  const quote = await quotes.findOne({ quoteID: params.id });  // If found, respond with the quote. If not, respond with a 404  if (quote) {    response.status = 200;    response.body = {      success: true,      data: quote,    };  } else {    response.status = 404;    response.body = {      success: false,      msg: "No quote found",    };  }};

To get all the quotes stored in the database, we create the getQuotes function.

// DESC: GET all Quotes// METHOD GET /api/quoteconst getQuotes = async ({ response }: { response: any }) => {  try {    // Find all quotes and convert them into an Array    const allQuotes = await quotes.find({}).toArray();    console.log(allQuotes);    if (allQuotes) {      response.status = 200;      response.body = {        success: true,        data: allQuotes,      };    } else {      response.status = 500;      response.body = {        success: false,        msg: "Internal Server Error",      };    }  } catch (err) {    response.body = {      success: false,      msg: err.toString(),    };  }};

For updating a particular quote, let's build the updateQuote function.

// DESC: UPDATE single quote// METHOD: PUT /api/quote/:idconst updateQuote = async ({  params,  request,  response,}: {  params: { id: string };  request: any;  response: any;}) => {  try {    // Search a quote in the DB and update with given values if found    const body = await request.body();    const inputQuote = await body.value;    await quotes.updateOne(      { quoteID: params.id },      { $set: { quote: inputQuote.quote, author: inputQuote.author } }    );    // Respond with the Updated Quote    const updatedQuote = await quotes.findOne({ quoteID: params.id });    response.status = 200;    response.body = {      success: true,      data: updatedQuote,    };  } catch (err) {    response.body = {      success: false,      msg: err.toString(),    };  }};

Now, creating the deleteQuote function.

// DESC: DELETE single quote// METHOD: DELETE /api/quote/:idconst deleteQuote = async ({  params,  response,}: {  params: { id: string };  request: any;  response: any;}) => {  try {    // Search for the given quote and drop it from the DB    await quotes.deleteOne({ quoteID: params.id });    response.status = 201;    response.body = {      success: true,      msg: "Product deleted",    };  } catch (err) {    response.body = {      success: false,      msg: err.toString(),    };  }};

Let's export all these functions so we can use them in routes.ts

export { getQuotes, getQuote, addQuote, updateQuote, deleteQuote };

We're almost done. Next, we'll bring in the controller.ts file in our router. Just add this line under the import statements in the routes.ts file.

import {  addQuote,  getQuotes,  getQuote,  updateQuote,  deleteQuote,} from "./controllers/products.ts";

To run the server, go to your project directory and execute this command
deno run --allow-all server.ts

Thats it! Your API should be running. Test it with Postman or RestClient

You can view the entire code here
Drop a on the repo if you like it. Feel free to open any issue or drop a comment if you face any problems or find a mistake somewhere.

If you like my content, please drop a follow or connect with me on my socials
Github - @NakshatraCodes
LinkedIn - Nakshatra Saxena


Original Link: https://dev.to/nakshcodes/create-your-first-restful-api-with-deno-oak-and-mongodb-48a7

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To