Introduction - In this blog, we’ll be building a RESTful CRUD (Create, Retrieve, Update, Delete) API with Node.js, Express and MongoDB. We’ll use Mongoose for interacting with the MongoDB instance.First we will know about the Express and Mongoose.

I’m assuming that you already know about Express,MongoDb, Mongoose. We will cover most of the coding part with some clear theory.

CRUD is an acronym for Create, Read, Update and Delete. It is a set of operations we get servers to execute (POST, GET, PUT and DELETE requests respectively). This is what each operation does:

●   Create (POST) - Make something

●   Read (GET)- Get something

●   Update (PUT) - Change something

●   Delete (DELETE)- Remove something

POST, GET, PUT, and DELETE requests let us construct Rest Api’s.

If we put CRUD, Express and MongoDB together into a single diagram, this is what it would look like:


Our Application

In this blog, We will be building a simple Note-Taking application. We will build Rest APIs for creating, listing, editing and deleting a Note.

We’ll start by building a simple web server and then move on to configuring the database, building the Note model and different routes for handling all the CRUD operations.

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

Also, In this post, we’ll heavily use ES6 features like let, const, arrow functions, promises etc. It’s good to familiarize yourself with these features. I recommend this re-introduction to Javascript to brush up these concepts.
Well! Now that we know what we are going to build, We need a name for our application. Let’s call our application UserCrud.

Creating the Application

1. First open up your terminal and create a new folder for the application or you can customize the path location.
$ mkdir user-crud-app

2. Initialize the application with a package.json file.

Go to the root folder of your application and typenpm initto initialize your app with a package.json file.
$ cd user-crud-app
$ npm init

Output Be Like

name: (node-easy-notes-app)
version: (1.0.0)
description:
entry point: server.js
test command:
git repository:
keywords: Express RestAPI MongoDB Mongoose
author: Amar Gupta
license: (ISC) MIT
About to write to /home/amarg3891/user-crud-app/package.json:
{
"name": "user-crud-app",
 "version": "1.0.0",
 "description": "",
 "main": "server.js",
 "scripts": {
   "test": "echo \"Error: no test specified\"&& exit 1"
 },
 "keywords": [
   "Express",
   "RestAPI",
   "MongoDB",
   "Mongoose"
     ],
 "author": "Amar Gupta",
 "license": "MIT"
}
Is this ok? (yes) yes
Above I’ve specified a file named server.js as the entry point of our application. We’ll create server.js file in the root directory of our projectFolder user-crud-app in the next section.
3. Install dependencies for our application

We will need express, mongoose and body-parser modules in our application. Let’s install them by typing the following command -

$ npm install express body-parser mongoose --save
I’ve used  --save  option to save all the dependencies in the  package.json  file. The final package.json file looks like this -
{
 "name": "user-crud-app",
 "version": "1.0.0",
 "description": "",
 "main": "server.js",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
   "Express",
   "RestAPI",
   "MongoDB",
   "Mongoose"
 ],
 "author": "Amar Gupta",
 "license": "MIT",
 "dependencies": {
   "body-parser": "^1.19.0",
   "express": "^4.17.1",
   "mongoose": "^5.13.7"
 }
}
Our application folder now has a package.jsonfile and a node_modules folder -
user-crud-app
   └── node_modules/
   └── package.json
Setting up the web server

Let’s now create the main entry point of our application. Create a new file named server.js in the root folder of the application with the following contents -

constexpress = require('express');

constbodyParser = 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())

app.use('/', route)

// define a simple route
app.get('/', (req, res) => {
   res.json({"message": "You are on the User-Crud-App"});
});

// listen for requests
app.listen(8080, () => {
   console.log("Server is listening on port 8080");
});
First, We have to import express and body-parser modules.
Then, We create an express app, and add two body-parsermiddlewares using express’s app.use()method.
A middlewareis a function that has access to the request and responseobjects. It can execute any code, transform the request object, or return a response.

After setting up modules on our root file server.js we will create a simple GET route which returns a message to the clients.

And also we have to set up a port for incoming connections.In this app we will use port 8080 but you can choose of your choice.
So now everything is setted up. We are going to run server http://localhost:8080 to access the route endpoint we just defined in above code.

$ node server.js
Server is listening on port 8080

Configuring and Connecting to the database
Basically we can write our connection code into server.js file but I don't want to mess code in one file so I’ll create a separate  folder config  into the root directory where we will keep all the configuration.

$ mkdir config
$ cd config

Now, Create a new file   database.config.js inside  config folder with the following contents -



module.exports = {
   url: 'mongodb://localhost:27017/User-crud-App'
}

Now we will  import the above database configuration in server.js and connect to the database using mongoose.
Add the below code to the server.jsfile after app.use(bodyParser.json())  line -

// Configuring the database
constdbConfig = require('./config/database.config.js');
constmongoose = require('mongoose');
mongoose.Promise = global.Promise;
// Connecting to the database
mongoose.connect(dbConfig.url, {
   useNewUrlParser: true
}).then(() => {
   console.log("Successfully connected to the database");    
}).catch(err => {
   console.log('Could not connect to the database. Exiting now...', err);
   process.exit();
});

Let’s run the server and make sure that you’re able to connect to the database -

$ node server
Server is listening on port 8080
Successfully connected to the database
Defining the User model in Mongoose

Next, We will define the  User model. Create a new folder called modelinside the root folder of the application.

$ mkdir models
$ cd models

Now, create a file called user.model.jsinside models folder with the below code -

constmongoose = require('mongoose');
constUserSchema = mongoose.Schema({
   name: String,
   email: String,
   address:String
}, {
   timestamps: true
});
module.exports = mongoose.model('User', UserSchema);

The User model contains a name ,email and an address field. I have also added a timestampsoption to the schema.

Mongoose uses this option to automatically add two new fields - createdAt and updatedAtto the schema.

Routes Endpoint using Express

And Next  is the routes for the User APIs. Create a new folder called routes at the root directory.

$ mkdir routes
$ cd routes

Now, create a new file called user.routes.jsinside routes folder with the below code -

const express = require('express')

const router = express.Router()

constcontrollers = require('../controllers/user.controller.js');

   // Create a new User
   router.post('/user', controllers.create);

// Retrieve all Users
   router.get('/users', controllers.findAll);

// Retrieve a single User with userId    router.get('/user/:userId', controllers.getOne);

// Update a User with userId    router.put('/user/:userId', controllers.updateOne);

// Delete a user with userId    router.delete('/user/:userId', controllers.delete);

module.exports = router



Note that We have added a requirestatement for note.controller.js file. We’ll define the controller file in the next heading . The controller will contain methods for handling all the CRUD operations. It will work  like a logic part .

Before defining the controller, let’s first include the routes in server.js. Add the following require statement before app.listen()line inside server.js file.

// Require User routes

const route = require('./routes/user.routes.js');

The Controller functions

Create a new folder called controllers, then create a new file called user.controller.js inside controllers folder with the following code -
const User = require('../models/user.model.js');

// Create and Save a new User

User.create= (req, res) => {

// Validate request

if(!User) {

returnres.status(400).send({

message: "User Not Found"

});

}

// Create a User

constuser = newUser({

name: req.body.name || "User",

email: req.body.email,
       address: req.body.address,

});

// Save User in the database

user.save()

.then(data => {

res.send(data);

}).catch(err => {

res.status(500).send({

message: err.message || "Some error occurred while creating the User."

});

});

};

// Retrieve and return all users from the database.

User.findAll= (req, res) => {

User.find()

.then(User => {

res.send(User);

}).catch(err => {

res.status(500).send({

message: err.message || "Some errors occurred while retrieving users."

});

});

};

// Find a single user with a userId

User.findOne= (req, res) => {

User.findById(req.params.userId)

.then(User => {

if(!User) {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}

res.send(User);

}).catch(err => {

if(err.kind === 'ObjectId') {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}

returnres.status(500).send({

message: "Error retrieving user with id " + req.params.userId

});

});

};

// Update a user identified by the userId in the request

User.update= (req, res) => {

// Validate Request

if(!User) {

returnres.status(400).send({

message: "User can not be empty"

});

}

// Find User and update it with the request body

User.findByIdAndUpdate(req.params.userId, {

name: req.body.name || "User",

email: req.body.email,
       address: req.body.address,

},{new: true})

.then(User => {

if(!User) {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}

res.send(User);

}).catch(err => {

if(err.kind === 'ObjectId') {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}

returnres.status(500).send({

message: "Error updating User with id " + req.params.userId

});

});

};


// Delete a user with the specified userId in the request

User.delete = (req, res) => {

User.findByIdAndRemove(req.params.userId)

.then(User => {

if(!User) {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}

res.send({message: "User deleted successfully!"});

}).catch(err => {

if(err.kind === 'ObjectId' || err.name === 'NotFound') {

return res.status(404).send({

message: "User not found with id " + req.params.userId

});

}
       return res.status(500).send({

message: "Could not delete user with id " + req.params.userId

});

});

};

module.exports = User

Now Let’s Test All Api’s

Creating a new User using POST /User API



After passing data into body output be like -

Retrieving all Users using GET /User API



Retrieving a single User using GET /user/:userId API


Updating a User using PUT /user/:userId API


After hitting update api output will be -


Deleting a User using DELETE /user/:userId API



Conclusion

In this blog, We learned how to build rest apis in node.js using express framework and mongodb.

You can find the code for this blog in my github repository.

Thanks for reading. See you in the next Blog...!