Building A CRUD REST API With MongoDB, Mongoose, And NodeJS
In this tutorial we’re going to see how to develop a REST API with create, retrieve, update, and delete (CRUD) endpoints using Node.js and the very popular Mongoose object document modeler (ODM) to interact with MongoDB.
#Prerequisite:
Before we start make sure you have development environment.
-
NPM 6.9.0
-
NodeJS 10.16.3
-
MongoDB 4.2.0
-
IDE (Atom or Visual Studio)
To bootstrap our NodeJS project, we need to verify that we have NodeJS, NPM (node package manager) and MongoDB installed on our machine. To do that, open your terminal or command prompt and run
Verify NPM version
npm -v
Verify NodeJS version
node -v
Verify MongoDB version
mongo --version
If you have’t installed any of the above mentioned, following are the links to install and configure NPM, NodeJS & MongoDB
After setting up and configuring the development environment, follow the steps to build the application
#Step 1: Initialize NodeJS project
To initialize the NodeJS project, first create a directory with the project name. Open command prompt / terminal and type following commands.
mkdir nodejs-mongodb-rest
Go to the project directory and initialize the NodeJS project
cd nodejs-mongodb-rest
Initialize NodeJs project with npm init
follow the wizard to setup the project.
npm init
Following is the initialization wizard output
Bhupeshs-MacBook-Pro:nodejs-mongodb-rest bhupeshsinghpadiyar$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (nodejs-mongodb-rest)
version: (1.0.0)
description: CRUD REST Application with NodeJS & MongoDB
entry point: (index.js)
test command:
git repository:
keywords: RESTFUL,API,NodeJS,json
author: Bhupesh Singh Padiyar
license: (ISC)
About to write to /Users/bhupeshsinghpadiyar/Documents/GitHubPersonal/nodejs-mongodb-rest/package.json:
{
"name": "nodejs-mongodb-rest",
"version": "1.0.0",
"description": "CRUD REST Application with NodeJS & MongoDB",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"RESTFUL",
"API",
"NodeJS",
"json"
],
"author": "Bhupesh Singh Padiyar",
"license": "ISC"
}
Is this OK? (yes) yes
Bhupeshs-MacBook-Pro:nodejs-mongodb-rest bhupeshsinghpadiyar$
At this point, you should verify that you have a package.json
file is available n your project root.
#Step 2: Configuring NodeJS with Express framework
We need to run a web server in order to make our API endpoint accessible to the browser, client application or a client tool like PostMan, we shall be using ExpressJS to achieve this.
Install ExpressJS with the following command
npm install express --save
#Step 3: Import the project to IDE
Use your preferred IDE to open the project directory and create a file index.js
This index.js
file is entry point fo our application. Add the following code to index.js
file.
index.js
// Import express
let express = require('express')
// Initialize the app
let app = express();
// Setup server port
var port = process.env.PORT || 8888;
// Send message for default URL
app.get('/', (req, res) => res.send('Welcome to NodeJS, Express Application'));
// Launch app to listen to specified port
app.listen(port, function () {
console.log("Running NodeJS, Express application on port " + port);
});
#Step 4: Run the Node application
Use the following command to run the application from terminal / command prompt
node index.js
Following is the output of the command
Bhupeshs-MacBook-Pro:nodejs-mongodb-rest bhupeshsinghpadiyar$ node index
Running NodeJS, Express application on port 8888
Head to http://localhost:8080
on your browser and you should see the output as following
#Step 5: Create routing, model and controller
Now our basic NodeJS application framework is ready. We will divide our NodeJS application in following three modules to maintain the modularity .
- Entity/Model - Mongo collection and entity mapping
- Routing - Defining REST API endpoints routes
- Controller - Controller to handle request and responses
To achieve this we will create three files in our project
- userModel.js
- api-routing.js
- userController.js
#Step 6: Mongoose installation, configuration & model mapping
In order to connect with Mongo DB we need to add MongoDB libraries.
Install mongoose:
Use following npm command to install.
npm install mongoose --save
Configure mongoose:
Once installation completed, we need to configure it in the application. Go to the index.js file, import mongoose & connect by providing the DB URL. Add the following piece of code to your index.js file.
let mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/users_rest', { useNewUrlParser: true, useUnifiedTopology: true});
var db = mongoose.connection;
// Added check for DB connection
if(!db)
console.log("Error connecting db")
else
console.log("Db connected successfully")
Here localhost:27017 is your database host and users_rest is the database name.
Mapping between MongoDB collection and the Model:
Once mongo configuration completed successfully, we need to map the MongoDB Collection and the model file in our code. Following are the user information that we have to save in MongoDB user collection,
- id
- firstName
- lastName
- age
- address
Go to userModel.js file that we created previously and add the mapping as follows. The updated userModel.js looks as follows.
var mongoose = require('mongoose');
// Setup schema
var userSchema = mongoose.Schema({
id: {
type: String
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
age: {
type: Number,
required: true
},
address: {
type: String,
required: true
},
createdOn: {
type: Date,
default: Date.now
},
updatedOn: {
type: Date,
default: Date.now
}
});
// Export User model
var User = module.exports = mongoose.model('user', userSchema);
module.exports.get = function (callback, limit) {
User.find(callback).limit(limit);
}
Here for each field we need to define the type of the field and some other optional parameters like required, default etc. For more info about the other mapping attributes , follow the mongoose official documentation.
The MongoDB and model mapping part have completed here.
#Step 7: Add routing for the controller.
MondoDB configuration and mapping part is done. Now we will add the controller layer to serve different kind of request i.e. GET, POST, PUT, DELETE
Inside userController.js file we will perform 5 basic CRUD operations.
- List all the users
- Get specific user by id
- Create user
- Update user
- Delete user
Following is the final userController.js file after adding all five CRUD operations. In case of success response we will be setting HTTP status code as 200 & In case of any error from mongoose, we will be sending the HTTP status code as 500 with the error message thrown
// Import contact model
User = require('./userModel');
// Handle index actions
exports.index = async function (req, res){
try {
const response = await User.find({});
res.status(200).json({
status: 200,
message: "Users retrieved successfully!!",
data: response == null ? [] : response
});
} catch(err) {
res.status(500).json({
status: 500,
message: err
});
}
};
// Handle create user actions
exports.new = async function (req, res) {
// Create User model Object
var user = new User();
user.firstName = req.body.firstName;
user.lastName = req.body.lastName;
user.email = req.body.email;
user.age = req.body.age;
user.address = req.body.address;
try {
// save the user and check for errors
const response = await user.save();
res.status(200).json({
status: 200,
message: "New User created successfully!!",
data: response
});
} catch (err) {
res.status(500).json({
status: 500,
message: err
});
}
};
// Handle view contact info
exports.view = async function (req, res) {
try {
// save the user and check for errors
const response = await User.findById(req.params.id);
res.status(200).json({
status: 200,
message: "User details fetched successfully!!",
data: response == null ? {} : response
});
} catch (err) {
res.status(500).json({
status: 500,
message: err
});
}
};
// Handle update user info
exports.update = async function (req, res) {
try {
// save the user and check for errors
const user = await User.findById(req.params.id);
user.firstName = req.body.firstName;
user.lastName = req.body.lastName;
user.email = req.body.email;
user.age = req.body.age;
user.address = req.body.address;
const saeUserResp = await user.save(req.params.id);
res.status(200).json({
status: 200,
message: "User Info updated successfully!!",
data: saeUserResp
});
} catch (err) {
res.status(500).json({
status: 500,
message: err
});
}
};
// Handle delete user
exports.delete = async function (req, res) {
try {
// save the user and check for errors
const deleteResponse = await User.remove({_id: req.params.id});
res.status(200).json({
status: 200,
message: "User Info updated successfully!!",
data: deleteResponse
});
} catch (err) {
res.status(500).json({
status: 500,
message: err
});
}
};
Here we have five different methods to perform CRUD operation.
- The first method index will be returning list of all the users from DB.
- The second method new will be creating the user in the DB
- The third method view will be returning details of specific user from the DB.
- The fourth method update will update details of specific user in the DB.
- The fifth method delete will perform delete operation to delete specific user’s data from the DB.
#Step 8: Add API routing for the controller.
Now we have to add the api routing in the api-routing.js file. This routing will decide for which controller and which method inside the controller we need to call based on the request method and api URL.
To achieve this add the following line inside your index.js file.
// Use Api routes in the App
app.use('/api', apiRoutes)
The above line means all the request coming from the /api URL will be redirected to the api-routes.js file. And inside this file we will be writing the redirection rules for the api based on their methods (GET, POST, PUT, DELETE).
Refer the following code in api-roures.js file
// Initialize express router
let router = require('express').Router();
// Set default API response
router.get('/', function (req, res) {
res.json({
status: '200',
message: 'Welcome to NodeJS, Express & Mongoose Application!',
});
});
// Import contact controller
var userController = require('./userController');
// Contact routes
router.route('/users')
.get(userController.index)
.post(userController.new);
router.route('/users/:id')
.get(userController.view)
.put(userController.update)
.delete(userController.delete);
// Export API routes
module.exports = router;
Here is the quick explanation of the code above in api-routes.js file.
- The default URL (/api) with GET type request will return simple JSON message (Welcome to NodeJS, Express & Mongoose Application!) will status code 200.
- HTTP Requests coming from the /api/users route with GET type method will perform get all the users list operation in the controller layer.
- HTTP Requests coming from the /api/users route with POST type method will perform create user operation in the controller layer.
- HTTP Requests coming from the /api/users/:id route with GET type method will perform get user by id operation in the controller layer. Here :id is the id of the specific user passed in request URL
- HTTP Requests coming from the /api/users/:id route with PUT type method will perform UPDATE operation for specific user in the controller layer. Here :id is the id of the specific user passed in request URL
- HTTP Requests coming from the /api/users/:id route with DELETE type method will perform DELETE operation for specific user in the controller layer. Here :id is the id of the specific user passed in request URL
#Step 9: Verify code in index.js file
After MongoDB configuration and ROUTING configuration, the final index.js file code is as follows.
// Import express
let express = require('express')
// Initialize the app
let app = express();
// Import Body parser
let bodyParser = require('body-parser');
// Import Mongoose
let mongoose = require('mongoose');
// Configure bodyparser to handle post requests
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// Connect to Mongoose and set connection variable
// Deprecated: mongoose.connect('mongodb://localhost/resthub');
mongoose.connect('mongodb://localhost:27017/users_rest', { useNewUrlParser: true, useUnifiedTopology: true});
var db = mongoose.connection;
// Added check for DB connection
if(!db)
console.log("Error connecting db")
else
console.log("Db connected successfully")
// Import routes
let apiRoutes = require("./api-routes")
// Setup server port
var port = process.env.PORT || 8888;
// Use Api routes in the App
app.use('/api', apiRoutes)
// Send message for default URL
app.get('/', (req, res) => res.send('Welcome to NodeJS, Express Application'));
// Launch app to listen to specified port
app.listen(port, function () {
console.log("Running NodeJS, Express application on port " + port);
});
#Step 10: Start the application and test the API endpoints.
Now we need to start the application and test the api endpoints
Start Application:
Start the application by the following command in the project root directory:
node index.js
Test API Endpoints:
In order to test the API endpoints you may use any REST client tools like POSTMAN, RESTCLIENT etc.
Following are the API endpoint, API method, API request body and response etc.
-
Create user API
API Endpoint:
`http://localhost:8888/api/users`
Request Method : POST
Request Body:
{ "firstName": "Bhupesh", "lastName": "Singh", "email": "bhupeshpadiyar.com@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480" }
Response Body:
{ "status": 200, "message": "New User created successfully!!", "data": { "_id": "5f8eccc5fa26160abafa9e47", "createdOn": "2020-10-20T11:40:53.171Z", "updatedOn": "2020-10-20T11:40:53.172Z", "firstName": "Bhupesh", "lastName": "Singh", "email": "bhupeshpadiyar.com@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480", "__v": 0 } }
-
Get all users data API
API Endpoint:
`http://localhost:8888/api/users`
Request Method : GET
Response Body:
{ "status": 200, "message": "Users retrieved successfully!!", "data": [ { "_id": "5f8eccc5fa26160abafa9e47", "createdOn": "2020-10-20T11:40:53.171Z", "updatedOn": "2020-10-20T11:40:53.172Z", "firstName": "Bhupesh", "lastName": "Singh", "email": "bhupeshpadiyar.com@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480", "__v": 0 }, { "_id": "5f8ecdf5fa26160abafa9e48", "createdOn": "2020-10-20T11:45:57.184Z", "updatedOn": "2020-10-20T11:45:57.184Z", "firstName": "Johny", "lastName": "Sins", "email": "johny.sins@gmail.com", "age": 41, "address": "Los Angeles, California, USA", "__v": 0 } ] }
-
Get individual user detail by ID
API Endpoint:
`http://localhost:8888/api/users/5f8eccc5fa26160abafa9e47`
Request Method : GET
Response Body:
{ "status": 200, "message": "User details fetched successfully!!", "data": { "_id": "5f8eccc5fa26160abafa9e47", "createdOn": "2020-10-20T11:40:53.171Z", "updatedOn": "2020-10-20T11:40:53.172Z", "firstName": "Bhupesh", "lastName": "Singh", "email": "bhupeshpadiyar.com@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480", "__v": 0 } }
-
Update individual user detail by ID
API Endpoint:
`http://localhost:8888/api/users/5f8eccc5fa26160abafa9e47`
Request Method : PUT
-
Request Body:
{ "firstName": "Bhupesh", "lastName": "Singh PADIYAR", "email": "xyz@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480" }
Response Body:
{ "status": 200, "message": "User Info updated successfully!!", "data": { "_id": "5f8eccc5fa26160abafa9e47", "createdOn": "2020-10-20T11:40:53.171Z", "updatedOn": "2020-10-20T11:40:53.172Z", "firstName": "Bhupesh", "lastName": "Singh PADIYAR", "email": "xyz@gmail.com", "age": 32, "address": "Mont Kiara, Kuala Lumpur, Malasysia, 50480", "__v": 0 } }
-
-
Delete individual user by ID
API Endpoint:
`http://localhost:8888/api/users/5f8eccc5fa26160abafa9e47`
Request Method : DELETE
Response Body:
{
"status": 200,
"message": "User Info updated successfully!!",
"data": {
"n": 1,
"ok": 1,
"deletedCount": 1
}
}
#Source Code:
You may Download the source code from the following GitHub link
https://github.com/bhupeshpadiyar/nodejs-mongodb-rest
Thank You. Happy Learning!!!
Search
Recent Posts
- Posts
- Stripe payment gateway integration in NodeJS
- Exam Preparation Guide: OCI Foundations 2020 Associate Certification (1Z0–1085–20)
- Authorize.Net hosted form payment gateway integration with Spring Boot
- Building A CRUD REST API With MongoDB, Mongoose, And NodeJS
- CRUD REST API Using Spring Boot, Spring Data and MongoDB
- CRUD REST API Using Spring Boot 2+, JPA, Hibernate, and MySQL
- How to run any Java Application as Windows Service?
- How to run Java Application as background service in Ubuntu OS?
- Deploying to Tomcat with Maven plugin