Open In App

What is REST API in Node.js ?

Improve
Improve
Like Article
Like
Save
Share
Report

A REST API is an application programming interface that adheres to the constraints of REST architectural style and enables interaction with RESTful web services. Interconnected networks make up the web. A web service is a set of open protocols and standards used for exchanging data between client-server applications. Web services that follow the REST architecture are known as RESTful web services.

What is an API?

The API (Application Programming Interface) is a set of commands, functions, or protocols that act as an intermediary that enables two applications to communicate. It is pretty common to track the delivery guy’s location when you order food from a food delivery application like Zomato. The Google Map API makes it possible for you to do this. Let’s understand API by the analogy of a restaurant. Whenever you visit a restaurant, the waiter helps you place your order. After taking your order, the waiter asks the chef to cook the dish you’d like. When the meal is ready, the waiter brings it to you. A waiter serves as an intermediary between the chef and the customer in this situation. The waiter receives a request (order) from the customer(client), conveys the request to the chef (server), and fetches the prepared dish (response).

REST: REST stands for REpresentational State Transfer. Rest is an architectural style for creating websites using the HTTP protocol. There are certain architectural constraints that developers should follow when building websites or APIs.

Let us understand what representational state transfer means.

Suppose we have a web client and a web server(API). The client requests a resource and the server fetches the response from its database. Resource refers to something that belongs exclusively to the server. When a client requests a resource via the restful API, the server sends a Representation of that resource. So, Representation is what the server sends as a response. A resource’s state at a particular moment in time is its state. The transfer is the transmission of data from server to client. Therefore, Representational State transfer means the transfer of the state of the Representation of the resource. These representations are transferred via HTTP through various formats, including  JSON (Javascript Object Notation), HTML,XML or plain text. The most popular file format is JSON because it can be read both by humans and machines.

As an example, employee data in JSON format

[    
   "employee":  
  {    
       "id": 1
       "name":   "Riya",    
       "salary": 50000,    
  }    
]    

Http protocol and verbs: We have already discussed that REST works on the HTTP Protocol, so let’s explore why we need one. REST is always about a resource(NOUN) and SOAP is all about action. Now, need the action counterpart to the noun-based resource to comprehend what we need to do with that product. The HyperText Transfer Protocol defines several methods (called verbs) for determining the action to be performed on a resource. The resource can be accessed by the URI (Uniform Resource Identifier) or the URL. HTTP verbs (or methods) include POST, GET, PUT, PATCH, and DELETE.  The GET method retrieves information from the system. POST method is used to create new resources. The PUT method is used for updating the database with an entirely new entry, replacing the previous one, or creating a new resource. The Patch method is used for partially updating the existing resource. You can better understand what PUT and PATCH methods do by looking at the following example, Amazon shipped you a bicycle that was broken. This issue could be resolved by either replacing the whole cycle (PUT) or just replacing the broken part (PATCH). The delete method is used to delete an existing resource. 

Why REST?

  • Separate client and server:  The separation between client and server makes it very easy for the protocol to be used independently for various development projects. It allows us to build loosely coupled applications, the client and the server can evolve Separately. 
    eg: The client and server may not be concerned about which software they use.
  • REST is independent of platform and languages. It can also adapt to a variety of syntaxes and working platforms, allowing you to work on various development-related projects.  eg: we can use windows or mac os
  • Flexibility and scalability: REST is truly scalable. This is due to the separation of client and server. This means the server doesn’t have to keep client requests in its body, or communicate with the clients.
  • Not constrained by one data format. Provides a flexible approach by serializing information in JSON and XML formats.
  • The HTTP cache can be used to optimize the network and increase efficiency.
  • Easy to use and learn.

Let’s make our own RESTful API  to have a better understanding. 

Approach: We will create a RESTFUL API called gfg-employees. We will insert employee data and send HTTP requests. In this process, we will fetch, modify and delete the employee data.Robo3T will be used for the database. Postman will be used to send requests. Below is the step-by-step implementation.

Step 1: Create a new directory, go to the terminal, and initialize NPM by running the following command.

npm init -y

Initializing npm 

Step 2: Install body-parser, mongoose, express

  • body-parser: A middleware responsible for parsing the incoming request body before it can be handled.
  • express:  node.js framework
  • mongoose: Mongoose connects MongoDB to the Express web application
npm i body-parser mongoose express 

Installing body-parser mongoose express 

Step 3: Create an app.js file in the current directory and set up the server. We will import the packages into our project and configure our server.

app.js




const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
  
const app = express();
  
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(express.static("public"));
  
app.listen(3000, function() {
    console.log("Server started on port 3000");
});


Step 4: Creating a database on Robo3T. Consider a database of employees with employee_name, employee_department, employee_salary fields.

{

    "employee_name" : "Riya Verma",
    "employee_department" : "IT",
    "employee_salary":"90000"
},
{

    "employee_name" : "Saransh Gupta",
    "employee_department" : "Finance",
    "employee_salary":"75000"
},
{

    "employee_name" : "Harsh Sehgal",
    "employee_department" : "Production",
    "employee_salary":"60000"
},
{

    "employee_name" : "Arihant Kumar",
    "employee_department" : "Marketing",
    "employee_salary":"85000"
},
{

    "employee_name" : "Ananya Sharma",
    "employee_department" : "Human Resource Management",
    "employee_salary":"50000"
}
  • Go to Robo3t and create a new connection.
  • Create a database named gfg-employees by clicking on the new connection button.
  • A database ‘gfg-employees’ will be created. Now click on it and create a new collection called ’employeedatas’
  • To insert documents, click on employeedatas and select insert document.
  • Copy each document from above and insert it one by one.
  • To view all the documents, click on employeedatas.

The following shows how to create a database and insert documents. 

Creating a database of employees

Step 5: Set up MongoDB and write the schema for our employee data to create models. To set up MongoDB, we will use a mongoose. We will connect our application to the MongoDB location and add the database name to the URL string. By default, MongoDB uses port 27017.

mongoose.connect("mongodb://localhost:27017/gfg-employees", {useNewUrlParser: true});

The schema defines the structure of our collection. We will create a schema named employeeSchema consisting of three fields – employee_name, employee_department, and employee_salary. 

const employeeSchema = {
 employee_name: String,
 employee_department: String,
 employee_salary : Number
};

Now we will create a model from the employeeSchema.

const EmployeeData = mongoose.model("EmployeeData", employeeSchema);

Add the following code to your existing code in app.js file. 

app.js




const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
  
const app = express();
  
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(express.static("public"));
  
// Connecting gfg-employees database to our express application 
  
  { useNewUrlParser: true });
  
  
// Writing schema for employee-data collection
const employeeSchema = {
    employee_name: String,
    employee_department: String,
    employee_salary: Number
};
  
// Creating a model around employeeSchema
const EmployeeData = mongoose.model(
  "EmployeeData", employeeSchema);
  
app.listen(3000, function() {
    console.log("Server started on port 3000");
});


Step 6: Accessing all the employees using the GET method. We can fetch all the employees by sending a get request by specifying the route of the resource and a callback function that handles the request.

app.get(route, (req,res)=>{
})

To retrieve all the employees, we have to find the employees and read them from the database.

<ModelName>.find({conditions},function(err,results){
// Using the result
});

Add the following code to your existing app.js file. 

app.js




// Fetching all the employees  
  
app.get("/employees", (req, res) => {
    EmployeeData.find((err, foundEmployees) => {
        if (!err) {
            res.send(foundEmployees)
        } else {
            res.send(err);
        }
    })
})


Step to run the application: Start your application by running the following command.

node app.js

Output: We can access the employees at localhost:3000/employees. 

Fetching all the employees by sending a GET request 

Step 7:  Create a new employee using the POST method. We will create a new employee that will be added to the database. Here, the client sends data to the server. We don’t have a front-end yet, but we do have a server that has access to our database. We will test our API using Postman, rather than creating a form or a front end. Our goal is to send a post request to our server.

We will use the post method:

app.post(route,(req,res)=>{
   ...
})

Once the client sends the post request we need to grab that data by req.body.

Head over to postman and send a post request to localhost:3000/employees. Under the body tab, change the encoding to form-url coding, and add the employee_name, employee_department, and employee_salary in key, along with the value that represents the data that we want to send along with the request.

key  value
employee_name Srikant Iyer
employee_department R&D
employee_salary 45000

Adding the fields in the body tab 

We need to save this employee in our database.

const <constantName>=new <ModelName>({
<fieldName>:<fielddata>,..
});

Add the following code to the previous code in the app.js file. Restart your server and send a post request using postman.

Output: Go to Robo3T and refresh your collection to view the added article. Now we have an extra entry. 

Sending a post request to add a new employee

Step 8: Fetching a specific employee. We will read a specific employee from our database using the findOne method.

<ModelName>.findone({conditions},(req,res)=>{
});

here, we will fetch the employee with the employee_name Ananya Sharma. 

Add the following code to your app.js file. 

app.js




// Fetching a specific employee
app.get("/employees/:employee_name", function(req, res) {
  
    Article.findOne({ employee_name: req.params.employee_name }, 
                     function(err, foundEmployees) {
        if (foundEmployees) {
            res.send(foundEmployees);
        } else {
            res.send("No employee matching that name was found.");
        }
    });
})


Output: We will specify the employee_name  in the URL and the employee whose name matches that will be displayed. We will use %20 in the URL to indicate a space between the Name and the Surname in the employee_name. Spaces are encoded as %20. Hence, we will get employee information from localhost:3000/employees/Ananya%20Sharma. 

Fetching a specific employee

Step 9:  Overwriting an employee with the PUT method. To replace an existing employee, we will send a put request.

app.put(route ,(req,res)=>{
...
});

We will update the employee using the Mongoose update method. The overwrite specifies that we want to replace the entire article.  

<ModelName>.update(
{conditions},
{updates},
{overwrite:true}
(err,results)=>{
})

Add the following code to your app.js file 

app.js




// Overwriting the employee data
app.put("/employees/:employee_name", (req, res) => {
    EmployeeData.updateOne(
        { employee_name: req.params.employee_name }, 
        { employee_name: req.body.employee_name, 
        employee_department: req.body.employee_department,
        employee_salary: req.body.employee_salary }, 
        { overwrite: true },
        function(err) {
            if (!err) {
                res.send(
"Successfully updated the selected employee.");
            }
        }
    );
})


In this case, we will change our employee data of employee_name Harsh Sehgal as follows: 

key value
employee_name Himanshu Raj
employee_department Developer
employee_salary 56000

by sending a put request to the route localhost:3000/employees/Harsh%20Sehgal

If the server finds a parameter with an employee_name of Harsh Sehgal, it will replace the employee_name with a new name, employee_department with a new department, and update the salary field as well. 

Overwriting the employee data by sending a PUT request 

Step 9:  Updating the salary of an employee using the PATCH method. We will update an existing employee by sending a Patch request with the name of the employee we wish to update. To update the employee, we must give the fields we want to change in the body tab. Now that we are changing only one field of an employee rather than the entire employee data, the overwrite method is not needed when we call the update method to update our database. To update the employee, we must give the fields we want to change in the body tab.

Add the following code in your app.js file to modify the employee data.

app.js




// Updating an employee 
app.patch("/employees/:employee_name", function(req, res) {
  
    EmployeeData.update({employee_name:req.params.employee_name }, 
    { $set: req.body },
        function(err) {
            if (!err) {
                res.send("Successfully updated employee's salary.");
            } else {
                res.send(err);
            }
        }
    );
})


Output: It Updates only the fields that we provide. The salary of an employee named Riya Verma gets updated to 9500

Updating the employee data by sending a PATCH request 

Step 10: Deleting all the employees using the DELETE method. To delete all the employees from our database we will use deleteMany mongoose method and send a delete request from the postman.

Add the following code to your app.js file. 

app.js




// Deleting all the employees
app.delete("/employees", function(req, res) {
  
   EmployeeData.deleteMany(function(err) {
        if (!err) {
            res.send("Successfully deleted all employees.");
        } else {
            res.send(err);
        }
    });
});


Output: We will send a delete request to localhost:3000/employees to remove all our employees. Visit Robo3T and refresh your collection. If we send a delete request from our postman, we will not observe any employees. 

Deleting all the employees

Final Code:

app.js




const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require('mongoose');
  
const app = express();
  
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(express.static("public"));
  
// Connecting gfg-employees database to our express application 
  
mongoose.connect(
   { useNewUrlParser: true }
);
  
// Writing schema for employee-data collection
const employeeSchema = {
    employee_name: String,
    employee_department: String,
    employee_salary: Number
};
  
// Creating a model around employeeSchema
const EmployeeData = mongoose.model(
  "EmployeeData", employeeSchema);
  
// Fetching all the employees  
app.get("/employees", (req, res) => {
    EmployeeData.find((err, foundEmployees) => {
        if (!err) {
            res.send(foundEmployees)
        } else {
            res.send(err);
        }
    })
})
  
// Posting a new employee
app.post("/employees", (req, res) => {
    const newEmployee = new EmployeeData({
        employee_name: req.body.employee_name,
        employee_department: req.body.employee_department,
        employee_salary: req.body.employee_salary
    });
  
    // Saving the employee
    newEmployee.save(function(err) {
        if (!err) {
            res.send("Successfully added a new employee.");
        } else {
            res.send(err);
        }
    });
})
  
// Fetching a specific employee
app.get("/employees/:employee_name", function(req, res) {
  
    EmployeeData.findOne({ employee_name: req.params.employee_name }, 
                         function(err, foundEmployees) {
        if (foundEmployees) {
            res.send(foundEmployees);
        } else {
            res.send("No employee matching that name was found.");
        }
    });
})
  
// Replacing a specific employee
app.put("/employees/:employee_name", (req, res) => {
  
    EmployeeData.update({ employee_name: req.params.employee_name }, 
                       { employee_name: req.body.employee_name, 
                        employee_department: req.body.employee_department, 
                        employee_salary: req.body.employee_salary },
                        { overwrite: true },
        function(err) {
            if (!err) {
                res.send("Successfully updated the selected employee.");
            }
        }
    );
})
  
// Updating an employee 
app.patch("/employees/:employee_name", function(req, res) {
  
    EmployeeData.update({ employee_name: req.params.employee_name },
    { $set: req.body },
        function(err) {
            if (!err) {
                res.send("Successfully updated employee's salary.");
            } else {
                res.send(err);
            }
        }
    );
})
  
// Deleting all the employees
app.delete("/employees", function(req, res) {
  
    EmployeeData.deleteMany(function(err) {
        if (!err) {
            res.send("Successfully deleted all employees.");
        } else {
            res.send(err);
        }
    });
});
  
  
app.listen(3000, function() {
    console.log("Server started on port 3000");
});




Last Updated : 08 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads