Creating a REST API with Node.js and Express.js for Beginners

Shivam GuptaShivam Gupta
8 min read

In this article, we will create a REST API using Node.js and Express.js, with MongoDB as the database.

But before let us understand what is REST API?

REST API stands for Representational State Transfer Application Programming Interface. It is a set of rules and principles for designing web services that enable communication between a client and a server over the internet. REST APIs use standard HTTP methods (such as GET, POST, PUT, PATCH, and DELETE) to perform operations on resources.

Now lets start to build the REST API

Step 1 : Setup

Create a new folder open in vs code and run this command

npm init

This command will prompt you with basic questions about the project and based on your responses, will automatically generate a package.json file

This package.json file is essential for managing a Node.js project’s dependencies, scripts, and metadata

Step 2 : Install Dependencies

For building the REST API we need some dependency to install on terminal run this command

npm i express mongoose nodemon body-parser

This command will add express, mongoose and nodemon to node_module directory and list it in package.json file

Express: Easy to use framework which have routing and middleware support

Mongoose: Interacting with MongoDB which provide a model based approach

Nodemon: To restart the server every time we make some changes

body-parser: To use URL encoded data in application

Step 3 : Creating Entry Point

Create a server.js file inside the same directory. It will server as a entry point for your application. Inside the server.js file write this code

import express from 'express'

const app = express()
app.use(express.json())

app.listen(4000,() =>{
console.log("Server is running on port 4000)
})

To use the correct import statement for ES Modules syntax, update your package.json file by adding "type": "module". If you prefer not to make this change, you can continue using the CommonJS syntax with: const express = require('express')

const app = express(): Creating an instance of an Express application app.use(express.json()): Middleware to parse JSON bodies in incoming requests

app.listen(4000,() =>{ console.log("Server is running on port 4000) }): Server is listing on port 4000 for the incoming request.

To execute the code, you can either run node server.js for a one-time execution or configure the package.json file to use npm start, which will automatically restart the server whenever changes are made.

"scripts": {
    "start": "nodemon index.js"
},

Step 4: Database Configuration

To create a database in MongoDB, visit MongoDB Atlas and log in or sign up. After logging in, create a new cluster and add your username, password, and IP address to the cluster's security settings. Obtain your connection string from the "Connect" section of the cluster dashboard. Now create a folder of Name database and create a file db.js inside it then, add the connection string to your db.js file to establish a connection between your Node.js application and MongoDB.

import mongoose from 'mongoose'
const  DBConnetion = async() =>{
const MongoURI = '<Your MongoDb Connection String>'
    try {
        await mongoose.connect(MongoURI)        
        console.log("database is successfully connected")
    } catch (error) {
        console.log(error )
    }
}
export default DBConnetion

With the MongoDB connection established, the next step is to define the schema layout for our application. A schema serves as a blueprint outlining the structure, data types, and constraints of the documents within a MongoDB collection. To organize our code efficiently, create a new folder named models and add a file named itemModel.js where the schema for the "Item" collection will be defined.

import mongoose from 'mongoose'

const itemSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, 'Name is required'],
    trim: true,
  },
  description: {
    type: String,
    required: [true, 'Description is required'],
  },
  price: {
    type: Number,
    required: [true, 'Price is required'],
    min: [0, 'Price cannot be negative'],
  },
  category: {
    type: String,
    enum: ['Electronics', 'Clothing', 'Food', 'Books', 'Other'],
    default: 'Other',
  },
  quantity: {
    type: Number,
    required: [true, 'Quantity is required'],
    min: [0, 'Quantity cannot be negative'],
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

const Item = mongoose.model('Item', itemSchema);

export default Item;

Let me explain each line of code

This code defines a Mongoose schema for an "Item" model in a MongoDB database, specifying the structure and validation rules for item documents. The itemSchema includes fields like name, description, price, category, quantity, and createdAt, each with their own data types and constraints: name and description are required strings, price is a required number that must be non-negative, category is a string restricted to specific values ('Electronics', 'Clothing', 'Food', 'Books', 'Other') with a default of 'Other', quantity is a required number that also cannot be negative, and createdAt is a date set to the current date by default. The schema is then used to create a Mongoose model called Item, which is exported for use in other parts of the application.

Step 4: Routing Part:

Now lets create the route for each HTTP request [Get, Post, Put, Delete]. Create a new folder of name routes and add a file of name itemRoutes.js

Step 4.1 : Importing Modules

import express from 'express';
import Item from '../models/itemModel';
const router = express.Router();

Here the express use to create the router and handle HTTP requests and Item for interact with database for CRUD operation

Step 4.2 : Route to Create a New Item

router.post('/api/v1/item/new', async (req, res) => {
  try {
    const item = await Item.create(req.body);
    res.status(201).json({
      success: true,
      item,
    });
  } catch (error) {
    res.status(400).json({ success: false, message: error.message });
  }
});

Here we define a POST route and the path for this url is /api/v1/item/new. In this code, req.body holds the client-sent data, and Item.create adds a new item to the database. res.status sets the response status code on success, it returns a JSON object with the item and a success message, on error it returns an error message and the appropriate status code.

Step 4.3 : Route to get all item

router.get('/api/v1/items', async (req, res) => {
  try {
    const items = await Item.find();
    res.status(200).json({
      success: true,
      items,
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});

Here we define a Get route and the path for this url is /api/v1/items.Here items.find retrieve all the items from database and res.status sets the response status code on success, it send a JSON object contains all item and a success message, on error it returns an error message and the appropriate status code.

Step 4.4: Route to Update an Item

router.put('/api/v1/item/:id', async (req, res) => {
  try {
    let item = await Item.findById(req.params.id);
    if (!item) {
      return res.status(404).json({ success: false, message: "Item not found" });
    }

    item = await Item.findByIdAndUpdate(req.params.id, req.body, {
      new: true,
      runValidators: true,
    });

    res.status(200).json({
      success: true,
      item,
    });
  } catch (error) {
    res.status(400).json({ success: false, message: error.message });
  }
});

The PUT method at /api/v1/item/:id updates an item by its ID from req.params.id. Item.findById locates the item, and if not found, returns a "not found" error. Item.findByIdAndUpdate updates the item with req.body, using { new: true, runValidators: true } to return the updated document and validate the update. res.status sends a JSON response with the updated item and a success message on success, or an error message with the appropriate status code on failure.

Step 4.5:Route to Delete an Item

router.delete('/api/v1/item/:id', async (req, res) => {
  try {
    const item = await Item.findById(req.params.id);
    if (!item) {
      return res.status(404).json({ success: false, message: "Item not found" });
    }

    await item.deleteOne();
    res.status(200).json({
      success: true,
      message: "Item deleted successfully",
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
});
export default router;

The router.delete('/api/v1/item/:id', ...) route deletes an item by its ID. It uses Item.findById(req.params.id) to find the item; if not found, it returns a 404 status with a "Item not found" message. If found, item.deleteOne() removes the item, and a 200 status with a success message is sent. Errors result in a 500 status with an error message.

Step 5: Update the Server.js File

We have successfully developed the REST API using Node.js and Express.js. Now update the server.js file as follows to ensure proper functionality.

import express from 'express';
import DBConnetion from './database/db.js';
import itemRoutes from './routes/itemRoutes.js';
import body-parser from 'body-parser';


const app = express();
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
DBConnetion();
app.use(itemRoutes);
app.listen(4000,() =>{
console.log("Server is running on port 4000);
})

Step 6: Test Your REST API

To test the APIs we've developed, I'm using Postman for this purpose. However, you are free to use alternative tools such as Insomnia or Hoppscotch if you prefer. Postman is available as a standalone application or as an extension within VS code

POST :

Let first test the POST by creating a new item. Enter this url http://localhost:4000/api/v1/item/new and choose post option then select Body->raw->json and past this code and click on enter

{
  "name": "Iphone 11",
  "description" :"This is latest mobile phone from apple",
  "price" : 150000,
  "category" : "Electronics",
  "quantity": 1
}

Pasting the screenshot for better understading

GET:

Enter this URL http://localhost:4000/api/v1/items for retriving all the items whic are save in the database and click on send button it will give all the item from database

PUT:

To update the price and quantity of an item, use the PUT method. Enter the following URL: http://localhost:4000/api/v1/item/66cc249c46bdc292a57c18ee (ensure you replace the item ID with the appropriate one). Provide the fields you wish to update in the request body.

Delete:

To delete an item, use the DELETE method. Enter the following URL: http://localhost:4000/api/v1/item/66cc249c46bdc292a57c18ee (make sure to replace the item ID with the correct one). Sending this request will remove the specified item from the database.

Let's Connect

If you like this article lets connect on LinkedIn https://www.linkedin.com/in/shivamgupta6418/

1
Subscribe to my newsletter

Read articles from Shivam Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Shivam Gupta
Shivam Gupta