Saturday, May 16 2020

Building a Restful CRUD API with Node.js Express and MongoDB

In this article we have explained about Building a Simple CRUD Restful app with Node, Express, and MongoDB. CRUD stands for Create, Read, Update and Delete. These are the basic operations that a simple web app would be designed to achieve. If you don’t know about REST before, you can read more about it here.

how-to-build-a-restful-api-in-node-js-with-express-js-mongodb

Getting Started

  1. Install Node.js from the Node.js website
  2. Create a directory called as node-restful-curd-app in your local machine.
  3. Open terminal and check your node version using this command node –version
  4. Initialize the application with a package.json file
cd node-restful-curd-app
npm init

name: (node-restful-crud-app) 
version: (1.0.0) 
description: simple restful crud app using node.js, express js and mongodb.
entry point: (index.js) app.js
test command: 
git repository: 
keywords: Express RestAPI MongoDB Mongoose
author: phpexpertise
license: (ISC) MIT

{
  "name": "node-restful-crud-app",
  "version": "1.0.0",
  "description": "simple restful crud app using node.js, express js and mongodb.",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "Express",
    "RestAPI",
    "MongoDB",
    "Mongoose"
  ],
  "author": "phpexpertise",
  "license": "MIT"
}

Is this ok? (yes) yes

Note: app.js is the entry point of our application.

Install Dependencies

We need to install packages using for our API. The packages are

Express JS: Express JS is the most popular framework which is used in node.js.

Mongoose: Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.

body-parser:  package that can be used to handle JSON requests.

Config: Configurations are stored in configuration files within your application, and can be overridden and extended by environment variables, command line parameters, or external sources.

npm install express body-parser mongoose --save

I’ve used –save option to save all dependencies in the package.json file. Open the package.json file looks like this –

{
  "name": "node-restful-crud-app",
  "version": "1.0.0",
  "description": "simple restful crud app using node.js, express js and mongodb.",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "Express",
    "RestAPI",
    "MongoDB",
    "Mongoose"
  ],
  "author": "phpexpertise",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mongoose": "^5.2.8",
    "config": "^3.3.1",
  }
}

Initializing the Server:

Create a new file, let’s name it is app.js directly inside the node-restful-crud-app directory

touch app.js

Open the app.js file and require all the dependencies we previously installed.

// app.js
const express = require('express');
const bodyParser = require('body-parser');

// initialize our express app
const app = express();

Finally, We listen port number 4000 for incoming connections.

const port = process.env.port || 4000;

app.listen(port, () => {
    console.log(`server running port number ${port}`)
});

Organizing our application:

Inside node-restful-crud-app directory, I will create following the four sub directories:

  1. controllers
  2. models
  3. routes
  4. config

We will be working with a design pattern called MVC(Model, View, Controller). Note: In this tutorial we didn’t use view concept and will do later.

App Configuration

I like to keep all configuration files for the app in a separate folder. Let’s create config folder in the root directory.

mkdir config
cd config

Now, create a default.json inside app/config folder with the following contents –

// bg_mongo is a test database.
{
    "DBHost": "mongodb://localhost:27017/bg_mongo"
}

Connection to the Database

I like to keep all the db related files in a separate folder. Let’s create models folder in the root directory.

mkdir models
cd models

Now, create db.js file inside app/models folder with following contents –

const config = require('config');

// MongoDB connection
const mongoose = require('mongoose');

mongoose.Promise = global.Promise;
mongoose.connect(config.DBHost, {useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error'));

Now, create product.model.js file inside app/models folder with following contents –

const mongoose = require('mongoose');

var Schema = mongoose.Schema;

let productSchema = new Schema({
    name: {
        type: String, 
        required: true, 
        max: 65, 
        trim: true
    },
    price: {
        type: Number, 
        required: true
    }
});

module.exports = mongoose.model('Product', productSchema);

Routes:

Create a new folder called routes inside the app folder.

mkdir routes
cd routes

Now, create a new file called product.route.js inside app/routes folder with the following contents –

const router = require('express').Router();

const product_controller = require('../controllers/product.controller');

router.get('/lists', product_controller.lists);
router.get('/get/:id', product_controller.getProduct);
router.post('/create', product_controller.createProduct);
router.put('/update/:id', product_controller.updateProduct);
router.delete('/delete/:id', product_controller.deleteProduct);

module.exports = router;

Note that We have added a require statement for product.controller.js file. We’ll define the controller file in the next section. The controller will contain methods for handling all the CRUD operations.

Handling CRUD Operations:

Create a new folder called controllers inside the app folder.

mkdir controllers
cd controllers

Now, create a new file called product.controller.js inside app/controllers folder with the following contents –

const productModel = require('../models/product.model');

Before doing crud operations, we have to require product.model.js file in this controller.

Retrieve all products:

exports.lists = async (req, res) => {
    const data =  await productModel.find({});
    try {
        res.json({products: data});
    } catch (err) {
        res.json({error: err});
    }
};

Retrieve single product:

exports.getProduct = async(req, res) => {
    const data = await productModel.findById(req.params.id);
    try {
        res.json({products: data});
    } catch (err) {
        res.json({error: err});
    }
};

Create new product:

exports.createProduct = async(req, res) => {
    let data = {
        name: req.body.name,
        price: req.body.price,
    };

    const Product = new productModel(data);
    try {
        await Product.save();
        res.json({message: "Product successfully added!", Product });
    } catch (err) {
        res.json({error: err});
    }
};

Update a product:

exports.updateProduct = async(req, res) => {
    let data = {
        name: req.body.name,
        price: req.body.price,
    };

    try {
        const Record = await productModel.findByIdAndUpdate(req.params.id, data, {useFindAndModify: false})
        await Record.save();
        res.json({products: Record});
    } catch (err) {
        res.json({error: err});
    }
};

Delete a product:

exports.deleteProduct = async(req, res) => {
    try {
        const data = await productModel.findByIdAndDelete(req.params.id)
        res.json({message: 'Product deleted successfully!'});
    } catch (err) {
        res.json({error: err});
    }
};

Postman:

Postman is a HTTP client that is used for testing, documenting and the development of APIs.

  1. Install Postman from their website.

Please see the below screenshots which we are tested this App through postman.

/Get method – All items

getAll-api-using-postman

/Get method – single item

get-api-using-postman

/POST method – create

create-api-using-postman

/PUT method – update item

update-api-using-postman

/DELETE method – delete item

delete-api-using-postman

Read article about Creating a RESTful API with HapiJS and NodeJS and MYSQL to click here.

Share Your Thoughts

phpexpertise

I’m Blogger and Programming Blog, Tutorials, PHP, MySQL, jQuery, Laravel, Wordpress and Codeigniter