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
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
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 linkedin.com/in/shivamgupta6418