REST API with Deno and MongoDB

Giwantha Sandeepa Wijekoon
Nerd For Tech
Published in
4 min readFeb 2, 2021

--

This article will show you how to build a simple REST API with Deno and MongoDB.

Deno - Deno is a secure runtime for TypeScript and JavaScript that is based on V8 JavaScript engine and Rust, which was created by Ryan Dahl the original creator of the Node.js.

Prerequisites - Deno preinstalled, Postman API client, MongoDB account, preferred code editor(Visual Studio Code), and preinstalled Deno extension for VScode.

Steps :

1. Create server.ts and import Oak middleware.

import { Application } from ‘https://deno.land/x/oak/mod.ts'

2. Creating a database.

Log in to MongoDB cloud Atlas and create a new cluster if you do not have one already. Leave everything as it is, and give a name to your cluster (In my case it is ‘DenoProducts’). Below is our cluster which was created.

Then go to Database Access>Add New Database User, provide a username and password, click on Add User.

After that, we need to allow Network Access, because by default we would not be able to connect to this database unless we whitelist the IP address. Therefore go to Network Access>Add IP Address, you can add your current IP address or allow access from anywhere.

Then go to your cluster >Connect>Connect to your application, copy your connection string.

Create a folder named db in your root directory, and create mongodb.ts file inside of it. Copy and paste the code below.

import { MongoClient } from “https://deno.land/x/mongo@v0.8.0/mod.ts";const client = new MongoClient();client.connectWithUri(“<Paste your connection string here>”);const db = client.database(‘products’);export default db

3. Creating a controller.

Create a folder named controller in your root directory, and create products.ts file inside of it. Inside this file, we need to perform CRUD functionalities for our API.

import { RouterContext } from ‘https://deno.land/x/oak/mod.ts'import db from ‘../db/mongodb.ts’const productsCollection = db.collection(‘products’)// @desc Get all the products// @route GET /broco/api/productsconst getProducts = async (ctx: RouterContext) => {const products = await productsCollection.find();ctx.response.body = products}// @route GET /broco/api/products/:idconst getProductsById = async (ctx: RouterContext) => {const id = ctx.params.id;const products = await productsCollection.findOne({_id: {$oid: id}})ctx.response.body = products}//@route POST /broco/api/productsconst addProducts = async (ctx: RouterContext) => {const {value: {name, uprice, description}} = await ctx.request.body()const products: any = {name,uprice,description,date: new Date()};const id = await productsCollection.insertOne(products)console.log(id)products._id = idctx.response.status = 201ctx.response.body = products}// @route PUT /broco/api/products/:idconst updateProducts = async (ctx: RouterContext) => {const id = ctx.params.id;const {value: {name, uprice, description}} = await ctx.request.body()const { modifiedCount } = await productsCollection.updateOne({_id: {$oid: id}}, {$set: {name,uprice,description}})if (!modifiedCount){ctx.response.status = 404ctx.response.body = {message: ‘Product does not exists’}return}ctx.response.body = await productsCollection.findOne({_id: {$oid: id}})}// @route DELETE /broco/api/products/:idconst deleteProducts = async (ctx: RouterContext) => {const id = ctx.params.idconst product = await productsCollection.deleteOne({_id: {$oid: id}})if(!product) {ctx.response.status = 404ctx.response.body = {message: ‘Product does not exists’}return}ctx.response.status = 204}export { getProducts, addProducts, getProductsById, updateProducts, deleteProducts }

4. Creating routes.

Create routes.ts file in your root directory and copy and paste the code below.

import { Router } from ‘https://deno.land/x/oak/mod.ts'import { getProducts, addProducts, getProductsById, updateProducts, deleteProducts } from ‘./controller/products.ts’const router = new Router()router.get(‘/broco/v1/products’, getProducts).get(‘/broco/v1/products/:id’, getProductsById).post(‘/broco/v1/products’, addProducts).put(‘/broco/v1/products/:id’, updateProducts).delete(‘/broco/v1/products/:id’, deleteProducts)export default router

Router - An interface for registering middleware that will run when certain HTTP methods and paths are requested, and it also provides a way to parameterize parts of the requested path.

get() - Register middleware for the specified route when the GET method is requested.

post() - Register middleware for the specified route when the POST method is requested.

put() - Register middleware for the specified route when the PUT method is requested.

delete() - Register middleware for the specified route when the DELETE method is requested.

5. Complete the server.ts file.

Register the middleware using .use() method and, then processes inbound requests against the middleware using .listen() method.

import { Application } from ‘https://deno.land/x/oak/mod.ts'import router from ‘./routes.ts’const port = 5000const app = new Application()app.use(router.routes())app.use(router.allowedMethods())console.log(`Server is running on port: ${port}`)await app.listen({ port })

6. Run the server.

Start the server using the following command.

deno run --allow-net --allow-write --allow-read --allow-plugin --unstable server.tsNOTE: Because the MongoDB plug-in API of the Deno is still not stable, the --unstable flag needs to be used.

7. Test the API with Postman API client.

Test the API using the following endpoints on http://localhost:5000 .

Congratulations……. 🥳, you have created a REST API with Deno and MongoDB.

Source Code: https://github.com/giwi97/octo-broccoli

--

--