CRUD Operations in Express, Nodejs and MongoDB
Tags: javascript, node, mongodb, express
Published: 2020-05-04 04:53:24

Are you new to backend development and just started up with the Express.js framework?
Then this blog may help you to get started, In this article, I will be starting up with creating a server and CRUD (**C**reate, **R**ead, **U**pdate and **D**elete) operations.

So let's get started with it.
## Step 1: Setting up the Server
The very first step when you are setting up a project for express is to create an app.js file which is the root file where we will be creating our server.
So we will first create a file app.js with the following content.
```javascript
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
/**
 * parse requests of content-type - application/json
 */
app.use(bodyParser.json());
/**
 * parse requests of content-type - application/x-www-form-urlencoded
 */
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
    res.json({"message": "Congratulations! you are working great!"});
});
app.listen(8000);
console.log("Listening to PORT 8000");
```
Here we have require(import) express and body-parser modules.
The express is the web framework which we will use to build REST API's and the bodyparser is the Node.js body parsing middleware which parses the request and creates the `req.body` object that we can access in our routes.Next, we have simply defines our get request to display a message congratulating you.
Your server now started and listening the port 8000.
Congratulations! you have completed the step 1 now let's move forward to our step 2.

## Step 2: Database Connectivity
After setting up the server we will be setting up our database connection, for that, we have to create another file in the root folder db.js with the following content.
```javascript
const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/TrainingProjectDb', {useNewUrlParser: true}, 
(err) => {
    if (!err) {
        console.log('Successfully Established Connection with MongoDB')
    }
    else {
        console.log('Failed to Establish Connection with MongoDB with Error: '+ err)
    }
});
module.exports = mongoose;
```
Here we have require the mongoose module. Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js .It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.
Now run the command `node app.js` to run your server and making the connection to db.Also, do not forget to import your db file in app.js.

Isn't this easy?
Let's move further with our CRUD operation.

## Step 3: Defining the User Model
 Now we will work on  CRUD operation for a User. So our first step towards it would be defining the model.
To make your code looks clean do make a separate folder for models and create a user_model.js file in it.
Now we will be defining our node model using mongoose.
```javascript
const mongoose = require("../db");
const schema = new mongoose.Schema(
  {
    email: {
      desc: "The user's email address.",
      trim: true,
      type: String,
      index: true,
      unique: true,
      required: true,
    },
    password: {
      desc: "user password",
      trim: true,
      type: String,
      required: true,
      select: false,
    },
    name: {
      desc: "The user's name.",
      trim: true,
      type: String,
      required: true,
    },
    age: {
      desc: "The users's age.",
      type: Number,
    },
    gender: {
      desc: "user gender.",
      trim: true,
      type: String,
      enum: ["Male", "Female", "Others"],
      default: "Others",
      required: true,
    },
    isActive: {
      desc: "is Active.",
      type: Boolean,
      default: true,
      required: true,
    },
    userType: {
      desc: "user roles.",
      trim: true,
      type: String,
      enum: ["Admin", "User"],
      default: "Admin",
      required: true,
    },
  },
  {
    strict: true,
    versionKey: false,
    timestamps: { createdAt: "createdAt", updatedAt: "updatedAt" },
  }
);

module.exports = mongoose.model("Users", schema);
```
Now we have created the model, you can edit the fields according to your needs.

## Step 4: Writing Controller functions
After creating the user model we now have to create the user controller file in the controller folder.
A controller is a file where all our business logic is written.
So we will be defining our CRUD operation in this file.
The first function we will be writing is to create a user.
### Creating a User and saving it to the database
```javascript
/**
 * User controller : All business logic goes here
 */
const User = require("../models/User");
const bcrypt = require("bcryptjs");
/**
 * this method is to create the user
 */
exports.create = (req, res) => {
  /**
   * validation request
   */
  if (!req.body.email || !req.body.password || !req.body.name) {
    return res.status(400).send({
      message: "Required field can not be empty",
    });
  }
  /**
   * Create a user
   */
  const user = new User({
    email: req.body.email,
    password: bcrypt.hashSync(req.body.password, 10),
    name: req.body.name,
    age: req.body.age,
    gender: req.body.gender,
    isActive: req.body.isActive,
    userType: req.body.userType,
  });
  /**
   * Save user to database
   */
  user
    .save()
    .then((data) => {
      res.send(data);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "Some error occurred while creating the User.",
      });
    });
};
```
### Finding all users
```javascript
/** 
 * Find all Users
 */
exports.findAll = (req, res) => {
  User.find()
    .sort({ name: -1 })
    .then((users) => {
      res.status(200).send(users);
    })
    .catch((err) => {
      res.status(500).send({
        message: err.message || "Error Occured",
      });
    });
};
```
Here we are using the `find()` function to find all users we can also use `findAll()` function for the same.
### Finding one user 
```javascript
/**
 * Find one User
 */
exports.findOne = (req, res) => {
  User.findById(req.params.id)
    .then((user) => {
      if (!user) {
        return res.status(404).send({
          message: "User not found with id " + req.params.id,
        });
      }
      res.status(200).send(user);
      console.log(user);
    })
    .catch((err) => {
      return res.status(500).send({
        message: "Error retrieving user with id " + req.params.id,
      });
    });
};
```
To find a single user we are finding it by id, we have a function `findById()` for achieving the same, we just have to pass the user id in params.

### Deleting a user
```javascript
/**
 * Delete a user with the specified id in the request
 */
exports.delete = (req, res) => {
  User.findByIdAndRemove(req.params.id)
    .then((user) => {
      if (!user) {
        return res.status(404).send({
          message: "User not found ",
        });
      }
      res.send({ message: "User deleted successfully!" });
    })
    .catch((err) => {
      return res.status(500).send({
        message: "Could not delete user ",
      });
    });
};
```
We can delete a user with the help of function `findByIdAndRemove()` by passing the id in param.

### Updating a user

```javascript
/**
 * Update a user with the specified id in the request
 */
exports.UpdateUser = (req, res) => {
  if (!req.body.email || !req.body.password || !req.body.name) {
    res.status(400).send({
      message: "required fields cannot be empty",
    });
  }
  User.findByIdAndUpdate(req.params.id, req.body, { new: true })
    .then((user) => {
      if (!user) {
        return res.status(404).send({
          message: "no user found",
        });
      }
      res.status(200).send(user);
    })
    .catch((err) => {
      return res.status(404).send({
        message: "error while updating the post",
      });
    });
};
```
The `{new: true}` option in the `findByIdAndUpdate()` method is used to return the modified document to the `then()` function instead of the original.

Congratulations! you're almost done. 

## Step 5: Working with Routes.

Now the last step left is to set up the routes. The easiest way of doing it is by maintaining the separate file for it.
So we will now be creating user_routes file in the routes folder with the following content.
```javascript
const express = require("express");
const router = express.Router();
const userControllr = require("../controllers/user_controller");

router.get("/", userControllr.findAll);
router.post("/", userControllr.create);
router.get("/:id", userControllr.findOne);
router.put("/:id", userControllr.UpdateUser);
router.delete("/:id", userControllr.delete);
module.exports = router;
```
Also after doing this do at these two line in the app.js file.
```javascript
app.use("/", router);
app.use("/users", require("./routes/user_route"));
```
Now! You're All done!
Don't forget to test these API's using Postman.
To test the create API you just have to select `POST` and add the URL 
`http://localhost:8000/users`
and add the following fields in the body as json.
```json
{
"email":"test@gmail.com",
"password":"test123",
"name":"test",
"age": 23,
"gender":"Female",
"isActive":true,
"userType":"User"
}
```
Now hit run you will get your response will all the data and an id.
For the API's where we had to add an id in param.
you just had to add that id in with the link in such a way
`http://localhost:8000/users/id`
here id refers to the value of id.

You can test all of them in this way and play around to add more validations to it or using different functions.

I hope this blog helps you.
**If you find this blog helpful just give a like or comment if you have any queries or suggestions.
[You can find complete code here in the Starter branch](https://github.com/Nidakhan786/Express-Mongo-Demo-Project-/tree/Starter).**