Develop NodeJs REST APIs using Express and MongoDB
Tags: mongodb
Published: 2022-08-19 18:45:17

Application Programming Interface(API) defines a set of rules for interacting with the server for data retrieval. APIs provide a way to communicate with different programs and allow the capabilities of one computer program to be used by another.
REST(Representational State Transfer) is a web standards architecture and an HTTP Protocol. In a REST architecture,  the client and the server can request to read, write, and update data simultaneously without the need to know anything about the client and server operations. REST API follows the design principles of the REST architecture.
In this article, we will create a REST API using Node.js and mongoDB.

## Getting Started
The article is designed in such a way that we will create a RESTful todo list API that will create, read, update and delete tasks.
### Requirements
- Node.js [[download](https://nodejs.org/en/download/)]
- MongoDB [[download](https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.1-signed.msi)]
- Postman [[download](https://www.postman.com/downloads/)]
- Visual Studio Code or Any text editor [[download](https://code.visualstudio.com/download)]

If you have not installed the listed softwares, download them from the official site and install them on your machine. Ensure that you have added mongodb and node.js path in the environment variables.

![env](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjxio1d2rhj0rae0qqdo.PNG)
Check the node.js and mongodb versions using the following command.
```
npm -v
mongo --version
```
### Setting up the project structure
- Open the command prompt and create a folder named todoListApi
```
mkdir todoListApi
```
- Move to the folder and initialize a node.js project using the following command,
```
cd todoListApi
npm init
```
`npm init` will prompt you to enter some basic information such as the app name, description, version, author, and keyword. Enter those information and press enter to complete the process. After the project creation, you will get a `package.json` file in the directory. `package.json` gives basic project information along with the project dependencies.

![npm init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9s0yjq5g2slgxbm8lvig.PNG)
- Open VSCode in the directory.
- Create a new file named index.js
- Create a new folder named `api`. Inside that,  create three folders - models, routes, and controllers.
- Create `todoListController.js` inside the `api/controller` folder, `todoListRoutes.js` inside the `api/routes` folder, and `todoListModel` inside the `api/models` folder.

The final folder structure should look like this:

![folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9c0lpngdtfgi35eu8yb.PNG)

### Setting up the server
- Open command prompt and type the following command to install express and body-parser package in your machine.

```
npm install express body-parser
```
- Open the `package.json` file and add the start command under scripts.

```
"start": "node index.js"
```
![start script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2wflsjrcduwb8r9lc9wy.PNG)
- Open index.js file and add the following code to it.

```
var express = require('express'),
app = express(),
port = process.env.PORT || 3000;
app.listen(port);console.log('todo list api server listening at ' + port);
```
- Start the server by running the following command.

```
npm start
```
![npm start](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ar14wzwmcd0k8nmc1wk.PNG)

### Setting up the schema
- Mongoose can be used to interact with the MongoDB instance. Install mongoose using the following command.
```
npm install mongoose
```
- Open todoListModel.js file from  api/models folder and add the following code to it.

```
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TaskSchema = new Schema({
  name: {
    type: String,
    required: 'Enter the name of the task'
  },
  created_date: {
    type: Date,
    default: Date.now
  },
  status: {
    type: [{
      type: String,
      enum: ['pending', 'ongoing', 'completed']
    }],
    default: ['pending']
  }
});
module.exports = mongoose.model('Tasks', TaskSchema);
```
We have created a model for the task collection. The task model contains a name, creation date and status. The status is defined as pending by default. 

### Setting up the routes
Routing helps to understand the way in which client requests are handled by the application endpoints. Each route has handler functions, which will be executed when the route is matched.
We can define two basic routes -  `/tasks`, and `/tasks/taskId`. In the next step, we will define the handler functions inside the controller.
Open `todoListRoutes.js` file from `api/routes` folder and add the following code to it.

```
'use strict';
module.exports = function(app) {
  var todoList = require('../controllers/todoListController');    
  app.route('/tasks')
    .get(todoList.listAllTasks)
    .post(todoList.createTask);  
  app.route('/tasks/:taskId')
    .get(todoList.readTask)
    .put(todoList.updateTask)
    .delete(todoList.deleteTask);
};
```
### Setting up the controller
Controllers are callback functions bound with routers to handle requests. 
Define controllers to create, update,delete and list the tasks. Create controllers named listAllTasks, createTask, readTask, updateTask, and deleteTask. Controllers use mongoose methods such as `find` (for selection), `findById` (for single selection), `findOneAndUpdate` (for updation), `save` and `remove` to make changes to the database.

Open `todoListController.js` file from  `api/controllers` folder and add the following code to it.

```
'use strict';
var mongoose = require('mongoose'),
  Task = mongoose.model('Tasks');
exports.listAllTasks = function(req, res) {
  Task.find({}, function(err, task) {
    if (err)
      res.send(err);
    res.json(task);
  });
};
exports.createTask = function(req, res) {
  var new_task = new Task(req.body);
  new_task.save(function(err, task) {
    if (err)
      res.send(err);
    res.json(task);
  });
};
exports.readTask = function(req, res) {
  Task.findById(req.params.taskId, function(err, task) {
    if (err)
      res.send(err);
    res.json(task);
  });
};
exports.updateTask = function(req, res) {
  Task.findOneAndUpdate({_id: req.params.taskId}, req.body, {new: true}, function(err, task) {
    if (err)
      res.send(err);
    res.json(task);
  });
};
exports.deleteTask = function(req, res) {
  Task.remove({
    _id: req.params.taskId
  }, function(err, task) {
    if (err)
      res.send(err);
    res.json({ message: 'Task successfully deleted' });
  });
};
```
### Finish the server setup
Let's connect to the database and finish the server configuration.
- Connect the database using the mongoose instance connection.
- Load the model using the `require()` method.
- Register the routes in the express app.
- Add the following code to the `index.js` file (replace the old content).

```
var express = require('express'),
  app = express(),
  port = process.env.PORT || 3000,
  mongoose = require('mongoose'),
  Task = require('./api/models/todoListModel'), 
  bodyParser = require('body-parser');
  
// mongoose instance connection url connection
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/Tododb', { useNewUrlParser: true, useUnifiedTopology: true });
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var routes = require('./api/routes/todoListRoutes'); 
//importing route
routes(app); 
//register the route
app.listen(port);
console.log('todo list api server listening at ' + port);
```
- Start the server using the following command.
```
npm start
```
There you have it! Your own todo list api in nodejs :)

### Test your app
Let's test the apis using postman. 
- Open postman and type `http://localhost:3000/tasks` in the enter request URL section and press enter. You can see an empty response in postman.
- Change the method to `POST` and the request body type as `x-www-form-urlencoded`. Provide name as the key and the task name as value. On clicking the Send button, you will get a response `200 ok`

### Handling Exceptions (optional)
If you have entered a wrong route `http://localhost:3000/task` instead of `http://localhost:3000/tasks` , the server responds with a message `Cannot GET /task`. Create a custom error message instead of the default error message by adding the following code in the server file (index.js).

```
app.use(function(req, res) {
  res.status(404).send({url: req.originalUrl + ' not found'})
});
```
Thanks for reading this article.
Thanks Gowri M Bhatt for reviewing the content.
If you enjoyed this article, please click on the heart button ♥ and share to help others find it!
The article is also available on [Medium](https://medium.com/@codemaker2016/develop-nodejs-rest-apis-using-express-and-mongodb-840ff885be39).
The full source code for this tutorial can be found here,
[GitHub - codemaker2015/rest-todo-list-api: Rest todo list api using nodejs and mongodb](https://github.com/codemaker2015/rest-todo-list-api)