Building API using DenoJs and Expressjs with Mongoose

Photo by Joan Gamell on Unsplash

Building API using DenoJs and Expressjs with Mongoose

Introduction

In this article we are going to build an API using denojs and expressjs, we will be using mongodb with mongoose. but before we continue let understand some terms

DenoJs : Is a JavaScript, TypeScript, and WebAssembly runtime with secure defaults and a great developer experience. It's built on V8, Rust, and Tokio. learn more

ExpressJs: Web Applications Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. learn more

Mongoose:: Elegant mongodb object modeling for node.js where mongodb is a NOSQL Database

Installation

I assume we all have mongodb install on our system, if not just google how to install mongodb and compass on your OS

follow this link to install denojs

Project setup

  • Create a folder called deno-api

  • Inside the deno-api folder, create the following folders (config, controller, model, router)

Database connection

Inside config folder, create a file db.ts and paste this code

import { createRequire } from "https://deno.land/std/node/module.ts";
const require = createRequire(import.meta.url);
import mongoose from 'npm:mongoose';

mongoose.connect('mongodb://localhost:27017/node-api')
  .then(() => console.log('Connected!'));

Model setup

Inside the model folder, create a file called todo.ts and paste this code

import mongoose from "npm:mongoose"

const todoSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true
    },
})

export default mongoose.model("Todo", todoSchema)

Controller setup

Inside the controller folder create a file called todo.ts and paste this code

import Todo from "../models/todo.ts"
import { Request, Response } from "npm:express"

// get one
const getTodo = async (req: Request, res: Response) => {
    try {
        const todo = await Todo.findById(req.params.id)
        if(!todo) {
            return res.status(404).json({message: "not found"})
        }
      return  res.status(200).json({todo})
    } catch (error) {
        res.json({ message: error.message })
    }
}

// get all
const getTodos = async (req: Request, res: Response) => {
    try {
        const todos = await Todo.find()
       return res.json(todos)
    } catch (error) {
        res.json({ message: error.message })
    }
}
// ceate new
const createTodo = async (req: Request, res: Response) => {
    const todo = new Todo({
        title: req.body.title,
    })
    try {
        const newTodo = await todo.save()
        res.status(201).json(newTodo)
    } catch (error) {
        res.status(400).json({ message: error.message })
    }
}

// update
const updateTodo = async (req: Request, res: Response) => {
    try {
        const todo = await Todo.findById(req.params.id)
        if (todo == null) {
            return res.status(404).json({ message: "Cannot find todo" })
        }
        if (req.body.title != null) {
            todo.title = req.body.title
        }

        const updatedTodo = await todo.save()
      return  res.json(updatedTodo)
    } catch (error) {
        res.status(500).json({ message: error.message })
    }
}

// delete
const deleteTodo = async (req: Request, res: Response) => {
    try {
        const user = await Todo.findById(req.params.id)
        if (user == null) {
            return res.status(404).json({ message: "Cannot find todo" })
        }
        await user.remove()
        res.json({ message: "Deleted todo" })
    } catch (error) {
        res.status(500).json({ message: error.message })
    }
}

export { getTodo, getTodos, createTodo, updateTodo, deleteTodo }

Route setup

Inside the router folder, create a file called todo.ts and paste this code

import express from "npm:express"
import {getTodo, getTodos, createTodo, updateTodo, deleteTodo } from "../controller/user.ts"

const router = express.Router()

router.get("/", getTodos)
router.get("/:id", getTodo)
router.post("/", createTodo)
router.put("/:id", updateTodo)
router.delete("/:id",deleteTodo)

export default router

App entry point

In the root folder create a file called main.ts and paste the following

import express from "npm:express";
import './config/db.ts'
import todo from "./router/todo.ts"

const app = express()
const port = 3000

app.use(express.json())

app.use("/todos", todo)

app.get('/', (req, res) => {
    res.send('Hello World!')
})

app.listen(port, () => {
    console.log(`app listening on port ${port}`)
})

Application start up

Remember to startup the mongodb server also

deno run --watch -A main.ts

Docker setup

create a Dockerfile in the root directory and paste

FROM denoland/deno:1.10.3

WORKDIR  /app

COPY . /app

EXPOSE 3000

CMD ["deno", "run", "--watch -A", "main.ts"]

source code