In this post, we are going to perform CRUD(Create, Read, Update and Delete) operations in Node, Express, and MongoDB and we will also follow Model View Controller (MVC) pattern.

Requirements

  • Download and Install Node Js.
  • Download and Install MongoDB.
  • Download and Install PostMan.
  • You should have Some basic knowledge about Javascript and ES6.
  • Curiosity and Interest ;)

Server Setup

We will initialize our project npm init.

npm init then we will add our dependencies express js and mongoose.

  • Express: It is the framework for the Node.js web application. It provides routing, templating, Middleware, etc.
  • Mongoose: It is an Object Data Modeling (ODM) library for MongoDB and Node.js. As we know that MongoDB is NoSQL. It is very flexible and we don't need to provide schema or structure. So mongoose helps us to provide MongoDB validations, Type Casting, Query Building, Hooks, etc.

To install the dependency in node, write npm i --save express and npm i --save mongoose in terminal.

{SS of dependency installation and package.json}

Now require the express then initialize the variable app and call express.

After that initialize another variable called PORT_NUMBER and assign value 9000. Our Server will listen to this number. To listen we will call app.listen() function then pass PORT_NUMBER as an argument, pass a callback function. where console Server is running on 9000.

const express = require("express")
const app = express()

const PORT_NUMBER = 9000
app.listen(PORT_NUMBER, () => {
  console.log(`Server is running on ${PORT_NUMBER}`)
})

Hello World Node Express API

Let's make an API.

app.get("/api", (req, res) => {
  return res.send("<h1> Hello World! </h1>")
})

In the above code we have called a functionget() then passed the path of the API and a callback function which has two arguments:req,res.

Express sends us two objects in this callback, which we called req and res, they represent the Request and the Response objects.

Request is the HTTP request. It gives us all the request information, including the request parameters, the headers, the body of the request, and more. The request object is enhanced version of the Node's own request object. This object has various properties like body, param, query, param etc.

Response is the HTTP response object that we’ll send to the client.

Hello World Node Express API

Let's create a small project where we will perform CRUD operations. Our Project Structure:

Project Structure Node Express

Middleware

Express has the middleware concept where middleware is the function that has access to the request, response object, and next middleware function in the application’s request-response cycle.

// app.js

// Express Middleware (Body Parser)
app.use(express.json())
// Our Middleware function to log some request's properties.
app.use((req, res, next) => {
  console.log("Method =======>>", req.method)
  console.log("Url =======>>", req.url)
  console.log("Body =======>>", req.body)
  console.log("Query =======>>", req.query)
  console.log("Params =======>>", req.params)
  next()
})

Project Structure Node Express

express.json() is the function that parses incoming request bodies in a middleware before your handlers, available under the req.body property.

Mongoose

Let's connect to our local MongoDB.

// app.js

const mongoose = require("mongoose")

// DB Connection
mongoose.connect(
  "mongodb://localhost:27017/codeparadox",
  { useNewUrlParser: true, useUnifiedTopology: true },
  error => {
    if (error) {
      console.log(error.message)
      throw error
    }
    console.log("MongoDB Connected Successfully.")
  }
)

// To log all queries that mongoose execute.
mongoose.set("debug", true)

Mongodb Mongoose Connection

MVC

Model View Controller (MVC) is a design pattern that divides application logic into three components which are interconnected.

  • Model
  • View
  • Controller

Let's create a schema for the post-collection.

Model

The Model Component is responsible for data-related logic.

// PostModel.js

const mongoose = require("mongoose")

const postSchema = mongoose.Schema(
  {
    title: {
      type: String,
      required: true,
    },
    description: {
      type: String,
      required: true,
    },
    author: {
      type: String,
      required: true,
    },
    created: {
      type: Number,
      default: Date.now(),
    },
  },
  {
    versionKey: false,
    timestamps: true,
  }
)

module.exports = mongoose.model("posts", postSchema)

In the above code, we have required mongoose to then call the schema function and pass our schema object. In schema we have to define keys and their data type, also they are required or not. we have also passed another argument which is also an object where mongoose we do not add version key in the record and we will add timestamps which will be createAt and updateAt key.

After that, we are calling the model function of the mongoose and where are passing a string as the name of our collection, which is post and another argument postSchema.

Now let's create a controller where we are going to perform our CRUD operations.

Controller

The Controller act as an interface between Model and View. It takes input from the view and interprets then informs the model to make a change according to the user's input.

// PostController.js

const PostModel = require("../Models/PostModel")

const postController = {
  // Create Post
  savePost: async (req, res) => {
    await new PostModel(req.body).save()
    return res.json({ message: "Post added successfully!" })
  },
  // Get Post By ID
  getPostById: async (req, res) => {
    // data validation
    if (!req.params.id) {
      return res.json({ error: "Id is required" })
    }
    const postBydId = await PostModel.findOne({ _id: req.params.id })
    return res.json({ data: postBydId })
  },
  // Get all Posts
  getPosts: async (req, res) => {
    const allPosts = await PostModel.find({})
    return res.json({ data: allPosts })
  },
  // Update Post
  updatePost: async (req, res) => {
    // data validation
    if (!req.body._id) {
      return res.json({ error: "Id is required" })
    }
    await PostModel.updateOne({ _id: req.body._id }, { $set: { ...req.body } })
    return res.json({ message: "Post updated successfully!" })
  },
  // Delete Post
  deletePost: async (req, res) => {
    // data validation
    if (!req.params.id) {
      return res.json({ error: "Id is required" })
    }
    await PostModel.deleteOne({ _id: req.params.id })
    return res.json({ message: "Post deleted successfully!" })
  },
}

module.exports = postController

All the functions are pretty straightforward, we have pass req and res and tried to validate our request then we have performed the MongoDB operations with the help of mongoose.

If you have read our MongoDB post, we have just done the same operations. With little change that now we are using mongoose and using some of its function like for insert, we are using save function to save a record.

After that, we have returned our data/message in the JSON form using res.json().

Routes

Routes could act as a view where it collects data or input from the user.

// app.js

// POST APIs
const postRoutes = require("./Routes/PostRoute")
app.use("/api/post", postRoutes)

In the above code, we are importing routes, using middleware where we are passing /api/post path which means any request starting with this path and with any method will execute the postRoutes.

// PostRoute.js

const express = require("express")
const router = express.Router()
const postController = require("../Controllers/PostController")

router.get("/", postController.getPosts)
router.get("/:id", postController.getPostById)
router.post("/", postController.savePost)
router.put("/", postController.updatePost)
router.delete("/:id", postController.deletePost)

module.exports = router

As we can see in the above code we have called Router class to create modular and mountable route handlers. A Router instance is a complete middleware.

So we have various methods like get, post, put, delete , patch etc and passed the path of the api and controller method.
In the path :id is the param so that we can get id from URL with the help of req.param property.

Let's run and check our all APIs.

POST

Create POST API Node MongoDB

GET

All Posts:

GET API Node MongoDB

Post By Id:

GET API Node MongoDB

PUT

PUT API Node MongoDB

Updated Post: After Update Node MongoDB

DELETE

DELETE API Node MongoDB

Deleted Post: After Delete Node MongoDB

Conclusion

We have implemented REST API and Crud Functionality using Node.js, Express and Mongodb. I didn't use an optimized way. It was one of the ways to implement. You can also check my other post about Vanilla Node.js (without any framework). Thanks for reading. if you found any issues or you have any query please contact.

Categories: Node JsJavascript