Building a Simple REST API Using Node.js and Express with MongoDB
Tags: node, mongodb, javascript, 100daysofcode
Published: 2020-07-06 18:45:25



This blog is all about, Building a Simple REST API (Create, Get, Update, Delete) Using `Node.js` and `Express` with `MongoDB`. We are going to use Mongoose for interconnection with the MongoDB instance.

Before start please install `Express`, `Node` and `MongoDB` in your machine if you have not done so already.

Let’s start…

### **Overview of Application**
We are going to build a simple book entry application with Rest APIs for creating, listing, editing and deleting a Book.

First, we will start by creating a simple web server and after that move on to configuring the database, building the Book model and different routes for handling all the CRUD operations.

Finally, we’ll test our REST APIs using Postman.

### **Creating the Application**
1 . Open the terminal and create a new folder with the application name.

`$ mkdir node-express-mongo-app`

2 . Initialize the application with a `package.json` file Go to the root folder of your application and type `npm init`
```
$ cd node-express-mongo-app
$ npm init
```
Follow the below wizard to setup your app with a `package.json` file.

```
package name: (express-mongo-app) 
version: (1.0.0) 
description: Rest API demo using node,express and mongoDB by IT Jugadu.
entry point: (index.js) server.js
test command: 
git repository: 
keywords: RestAPI Express Node MongoDB Books
author: itjugadu
license: (ISC) 
About to write to /home/lcom67/Desktop/node-express-mongo-app/package.json:

{
  "name": "express-mongo-app",
  "version": "1.0.0",
  "description": "Rest API demo using node,express and mongoDB by IT Jugadu.",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "RestAPI",
    "Express",
    "Node",
    "MongoDB",
    "Books"
  ],
  "author": "itjugadu",
  "license": "ISC"
}

Is this OK? (yes) yes
```

3 . Install dependencies

We are going to `install express`, `mongoose` and `body-parser` modules in our application by the following command -

`$ npm install express body-parser mongoose --save`

Here we used the `--save` option to save all the dependencies in the `package.json` file. After this `package.json` file looks like this -
```
{
 "name": "express-mongo-app",
 "version": "1.0.0",
 "description": "Rest API demo using node,express and mongoDB by IT Jugadu.",
 "main": "server.js",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
   "RestAPI",
   "Express",
   "Node",
   "MongoDB",
   "Books"
 ],
 "author": "itjugadu",
 "license": "ISC",
 "dependencies": {
   "body-parser": "^1.19.0",
   "express": "^4.17.1",
   "mongoose": "^5.9.21"
 }
}
```

### **Creating the web server**

We are going to create a `server.js` file in root folder of application  which will be main entry point for our application.
```
const express = require('express');
const bodyParser = require('body-parser');

// create express app
const app = express();

// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))

// parse requests of content-type - application/json
app.use(bodyParser.json())

// define a simple route
app.get('/', (req, res) => {
   res.json({"message": "Welcome to ExpressMongoApp application. Created by IT Jugadu"});
});

// listen for requests
app.listen(3000, () => {
   console.log("Server is listening on port 3000");
});
```

Let’s now run the server and open the [http://localhost:3000] in browser to access the GET route which returns a welcome message to the clients.

```
$ node server.js 
Server is listening on port 3000
```

In browser when you will open [http://localhost:3000] it will give message like below :
```
{"message":"Welcome to ExpressMongoApp application. Created by IT Jugadu"}
```

### **Configuring and Connecting to the database**

Always  keep all the configurations for the app in a separate folder. Let’s create a new folder config in the root folder of our application for keeping all the configurations -
```
$ mkdir config
$ cd config
```

Create a new file `development.config.js` inside config folder with the following contents -
```
module.exports = {
    url: 'mongodb://localhost:27017/express-mongo-app'
}
```

We are going to import the above database configuration in `server.js` and connect to the database using mongoose.
Add the following code to the `server.js` file after `app.use(bodyParser.json())` line -

```
// Configuring the database
const dbConfig = require('./config/development.config.js');
const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

// Connecting to the database
mongoose.connect(dbConfig.url, {
   useNewUrlParser: true
}).then(() => {
   console.log("Successfully connected to the express-mongo-app database");
}).catch(err => {
   console.log('Could not connect to the database. Exiting now...', err);
   process.exit();
});
```

Now run the server and make sure that you’re able to connect to the database if all is going correct you will see message like below -

```
$ node server.js
Server is listening on port 3000
Successfully connected to the express-mongo-app database
```
### **Creating the Book model in Mongoose**

Now we are going to create the `Book model`. Create a new folder called `app` inside the root folder of the application, then create another folder called `models` inside the `app` folder -

```
$ mkdir -p app/models
$ cd app/models
```
Now inside `app/models` folder create a file called `book.model.js` with the following contents -

```
const mongoose = require('mongoose');

const BookSchema = mongoose.Schema({
   title: {
    type: String,
    required: true  
   },
   author: String
}, {
   timestamps: true
});

module.exports = mongoose.model('Book', BookSchema);
```

**Note:** In model `title` is required. Means without `title` we can not insert record in book model.

### **Creating Routes using Express**

Create a new folder called routes inside the app folder.
```
$ mkdir app/routes
$ cd app/routes
```
Now, create a new file called `book.routes.js` inside `app/routes` enter below code - 

```
module.exports = (app) => {
   const books = require('../controllers/book.controller.js');

   // Create a new Book
   app.post('/books', books.create);

   // Get all Books
   app.get('/books', books.getAll);

   // Get a single Book with bookId
   app.get('/books/:bookId', books.getById);

   // Update a Book with bookId
   app.put('/books/:bookId', books.update);

   // Delete a Book with bookId
   app.delete('/books/:bookId', books.delete);
}
```

In the above routes code we have required the controller `book.controller.js` but still we did not define controller, let’s create controller.

First include below line of code into the `server.js` before `app.listen()` line.
```
// Require Books routes
require('./app/routes/book.routes.js')(app);
```

### **Creating Controller**

We are going to create a controller inside the `app/controllers` folder with the name `book.controller.js`.

In controller file first require the Book model like below -
```
const Book= require('../models/book.model.js');
```

After this we will implement the CURD (create, getAll, getById,update and delete) method in `book.controller.js` -

### **Creating a new Book** 
Add this function in  `book.controller.js`

```
const Book= require('../models/book.model.js');

// Create and Save a new Book
exports.create = (req, res) => {
   // Validate request because in model we required the title
   if(!req.body.title) {
       return res.status(400).send({
           message: "Please enter book title."
       });
   }

   // Create a book
   const book = new Book({
       title: req.body.title,
       author: req.body.author || 'IT Jugadu'
   });

   // Save Book in the database
   book.save()
       .then(oBook => {
           res.send(oBook);
       }).catch(err => {
       res.status(500).send({
           message: err.message || "Some error occurred while creating the Book."
       });
   });
};
```

### **Get all Book**
Add this function in the `book.controller.js` below the `create` method.

```
// Get all and return all books.
exports.getAll = (req, res) => {
   Book.find()
       .then(oBook => {
           res.send(oBook);
       }).catch(err => {
       res.status(500).send({
           message: err.message || "Some error occurred while retrieving the book."
       });
   });
};
```

### **Get the single Book**
Add this function in the `book.controller.js` below the `getAll` method.

```
// Get a single book with a bookId
exports.getById = (req, res) => {
   Book.findById(req.params.bookId)
       .then(oBook => {
           if(oBook) {
               res.send(oBook);
           }
           return res.status(404).send({
               message: "Book not exist with id " + req.params.bookId
           });
       }).catch(err => {
       if(err.kind === 'ObjectId') {
           return res.status(404).send({
               message: "Book not exist with id " + req.params.bookId
           });
       }
       return res.status(500).send({
           message: "Error retrieving book with id " + req.params.bookId
       });
   });
};
```

### **Updating the Book**
Add this function in the `book.controller.js` below the `getById` method.

```
// Update a book by the bookId
exports.update = (req, res) => {
   // Validate Request because title is required
   if(!req.body.title) {
       return res.status(400).send({
           message: "Please enter book title."
       });
   }

   // Find book and update it
   Book.findByIdAndUpdate(req.params.bookId, {
       title: req.body.title,
       author: req.body.author || "IT jugadu"
   }, {new: true})
       .then(oBook => {
           if(oBook) {
               res.send(oBook);
           }
           return res.status(404).send({
               message: "Book does not exist with bookId " + req.params.bookId
           });

       }).catch(err => {
       if(err.kind === 'ObjectId') {
           return res.status(404).send({
               message: "Book does not exist with bookId " + req.params.bookId
           });
       }
       return res.status(500).send({
           message: "Some error occurred while retrieving the book with bookId" + req.params.bookId
       });
   });
};
```

### **Deleting the Book**
Add this function in the `book.controller.js` below the `Update` method.

```
// Delete the Book with the bookId
exports.delete = (req, res) => {
   Book.findByIdAndRemove(req.params.bookId)
       .then(oBook => {
           if(oBook) {
               res.send({message: "Book has been deleted successfully!"});
           }
           return res.status(404).send({
               message: "Book not exist with bookId" + req.params.bookId
           });
       }).catch(err => {
       if(err.kind === 'ObjectId' || err.name === 'NotFound') {
           return res.status(404).send({
               message: "Book not exist with bookId" + req.params.bookId
           });
       }
       return res.status(500).send({
           message: "Some error occurred while deleting the book with bookId" + req.params.bookId
       });
   });
};
```


### **Testing with Postman**
Let’s start with the postman…

#### **Creating the new Book using POST `/books` API**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/szuvbu9fy161q40qtqzt.png)

#### **Get all Books using GET `/books` API**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dcz3ozfs1a5detod47ee.png)


#### **Get single Book using GET `/books/:bookId` API**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/h49lf3l8uauusccec0dv.png)

#### **Update the Book using PUT `/books/:bookId` API**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yhicywa4v0qu3gj2yb94.png)


#### **Delete a Book using DELETE `/books/:bookId` API**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/72b60x0a67onh1kef1qa.png)

### **Conclusions and resources**
 Thanks for reading and great job :smile: on following the guide.

We learned how to Building a Simple REST API Using Node.js and Express with MongoDB

You can find the code for this blog in my github repository. 
{% github https://github.com/itjugadu/node-express-mongo-app %}
Please ask any questions that you might have in the comment.