Skip to content

How to Build a Rest API With Nodejs and Express

Spread the love

For several years, NodeJS, often accompanied by its Express Framework, has made a name for itself in the world of web development. At the same time, the REST API has established itself as a reference for data exchange between servers and clients. The Node JS REST API stack has become a suitable choice in the design of web services.

This is not a tutorial but a guide, in which I’ll show you how to build a REST API with Nodejs and Express.

How to build a REST API with Nodejs and Express

Why use Node JS to build a REST API?

Building a Node JS API is a choice that is often relevant for the following reasons:

  1. It’s non-blocking processing of requests.
    NodeJS only has one thread. That is, there is only one “engine” available to process incoming requests to the server. However, Node JS has the ability to outsource “blocking” functions to the callback queue, allowing it to come back to process other incoming requests very quickly.
  2. Its performance and scalability
    NodeJS, being able to process several requests in a non-blocking way, coupled with its modularity, its performance within the framework of an API is remarkable. The design of a Node JS API makes it possible to multiply the instances of the modules which are under pressure from incoming calls.
  3. The JavaScript ecosystem and open source packages available
    NPM is the registry (which could be translated as a library) that hosts all the libraries. Whatever your need, there is surely a library to help you code your functionality. This richness of the ecosystem makes the development of a Node JS API faster.

Building a Node API with Express

In this guide, we’ll create a very simple REST API in order for you to understand each element that makes it up. We’re not going to run some tests and skip some best practices that aren’t within the scope of this guide.

Create an Express Server

Your Node JS API is primarily a web server listening to incoming HTTP requests. To start this web server, we will use the Express framework.

Start the Node JS API project

  1. Create your future API directory and navigate inside
  2. Enter the command npm init and answer the questions
  3. Create an index.js
npm-init--y
You can skip this step with npm init -y command

You will now have a package.json file in your directory, which will contain various project information and which will contain the dependencies that will be installed there.

package.json file
The npm init command generates the package.json file, which is the skeleton of your API and its dependencies.

Adding Express to our Node JS API

Now go back to your terminal and type the following command:

npm install express
npm-install-expresss
Installation d’Express JS via le terminal

The purpose of this command is to download from the NPM registry and then install the express library as well as all the libraries that express needs to run in your working directory, in the node_modules folder. NPM will also add it to your package.json in the dependencies.

ℹ️ In some online tutorials, you will find the option --save or -s after the npm install command. Be aware that before version 5.0 of NPM, you had to pass this option to find the dependency added in the package.json. However, since version 5.0, as soon as you place the npm install command, the library is by default added to the package.json. It is no longer necessary to pass the option -s or --save

❓ Why do we need to add the dependency in package.json?
ℹ️ For a Node JS API project or any other Node project to be taken over by another developer or deployed to a remote server, the package.json file MUST reference all the libraries the application needs to work well. You will not upload your whole application with the node_modules directory but just your code and the package.json. The server will be in charge of making a npm install to retrieve all dependencies.

Creating the Express server in our index.js file

Now that Express is available in our project, we can create the server. Let’s start by integrating the express library into our index.js file:

const express = require('express');
const app = express();

The require('express') is used to import the express library and its functions into our code. The constant app is the instantiation of an Express object, which will contain our server and the methods we will need to make it work.

❓ You may have seen the syntax import express from 'express'? This import syntax is based on ES6. This syntax is widely used in frontend development because it allows you to import only the methods that are used and to reduce the size of the JavaScript file to be loaded by the browser. In the case of a Node JS API, the code is executed on a server. The gain is not as important as in the front-end. Switching to an import syntax will require more configuration work than a syntax using require

For the moment, your server is prepared but not launched yet. If you type in localhost:8080 from your browser, you should get an error.

For our server to be able to listen, we must now use the method listen provided in app and specify a port. Most often in development, we use 8080, 3000, or 8000. It doesn’t matter as long as you don’t have other applications running locally on that same port.

app.listen(8080, () => {
  console.log('Server Listening)       
});

By issuing the command node index.js in your terminal, it will show that your server is listening. This means that everything is working fine. If there is an error, you will see an error message on your terminal.

localhost get nodejs
Your Node server is listening but doesn’t know what to do right now.

If you go to your browser at localhost:8080(or the other port you choose), your server responds to your browser. Having no route configured for the moment, it returns this error Cannot GET / but it is indeed functional.

Defining a resource and its routes

Now that your server is up and running, it’s time to define the heart of your API: its resources.

Defining the resources of our Node JS API

For our example, we will take the case of a company operating long-term car parks and taking reservations from its customers. We will need the following features:

  • Create a car park
  • List all car parks
  • Retrieve details of a specific car park
  • Delete a parking
  • Make reservations for a space in a car park
  • List all reservations
  • View details of a specific booking
  • Delete a reservation

These operations are more commonly called CRUD, for CREATE, READ, UPDATE, DELETE. In our example, our Node JS API has two resources: Parking and Reservation.

Creation of routes

The REST API standard dictates that our routes be centered around our resources and that the HTTP method used reflects the intent of the action. In our case we will need the following routes:

  • GET /parking
  • GET /parking/:id
  • POST /parking
  • PUT /parking/:id
  • DELETE /parking/:id

Reservations being a sub-resource of the parking resource, we will have to create the following routes:

  • GET /parking/:id/reservations
  • GET /parking/:id/reservations/:idReservation
  • POST /parking/:id/reservations
  • PUT /parking/:id/reservations/:idReservation
  • DELETE /parking/:id/reservations/:idReservation

For our Node JS API to work, we need sample data.

The purpose of this guide is to help you understand how an API works. We are not going to connect a real database in this guide. We will instead use a JSON file containing sample data to manipulate our API.
To download this file, click here then place it at the root of your working directory.

Let’s start by defining the GET /parking route.
The purpose of this route is to retrieve all the parking lots in our data. Let’s modify our index.js :

const express = require('express');
const app = express();

app.get('/parking', (req,res) => {
    res.send("List of parkings")
});

app.listen(8080, () => {
    console.log("Server Listening")
});

Express’s .get method allows you to define a GET route. It takes as first parameter a String which defined the route to listen to and a callback, which is the function to execute if this route is called. This callback takes the object as a parameter req, which takes all the data provided by the request, and the object res, provided by express, which contains the methods that’ll respond to the request that just arrived.

In this code, when a GET request arrives on the URL localhost:8080/parking, the server is instructed to send the String “List of parking lots”.

Shut down your node server if it’s still running (with the ctrl+c command in the terminal) and run the command again node index.js in order to take the changes into account.

ℹ️ For every modification in the code of your Node JS API, you will have to restart the server so that they are taken into account. Nevertheless, you may use Nodemon which allows you to automatically restart your node server each time you save your file. To install it, enter the command npm install nodemon -g then when you first launch your server, use the command nodemon instead of node index.js

Now that our route is working and is able to receive the incoming request, we will be able to return the parking data instead of just having a string:

const express = require('express');
const app = express();
const parking = require('./parking.json');

app.get('/parking', (req,res) => {
    res.status(200).json(parking)
});

app.listen(8080, () => {
    console.log("Server Listening")
});

We replaced the method send by the method JSON. Indeed our REST API will return a JSON file to the client and not text or an HTML file. We also added status 200, which is the HTTP response code telling the client that their request was completed successfully.

API response
Your API returns the data you asked for

Our GET /Parking route is now complete. We now need to set up the following routes using JavaScript methods to meet our needs.

The GET /parking/:id route is as follows. We need to retrieve the route id from the URL to display only the JSON of this parking lot in the response. This id can be found in the params, in the object req, sent by the browser.

Let’s go back to our index.js :

const express = require('express')
const app = express()
const parkings = require('./parking.json')

app.get('/parking', (req,res) => {
    res.status(200).json(parking)
})

app.get('/parking/:id', (req,res) => {
    const id = parseInt(req.params.id)
    const parking = parking.find(parking => parking.id === id)
    res.status(200).json(parking)
})

app.listen(8080, () => {
    console.log("Server Listening")
})

We retrieve the id requested by the client in params the request As my route has defined ‘/:id’, the value passed in the param will be as an object containing the key ” id “. The value of req.params.id contains what is sent in the URL, as a String. As the id of each car park is in the form of a Number, it is first necessary to transform the params from String to Number. Then, you have to search in the parking lots to find the one with the id corresponding to the one passed in the URL.

Let’s go to the POST /parking route to be able to create a new parking lot.

To create a new car park via your Node JS API, you will have to send the server the data relating to this new element, such as its name, its type, etc. When it comes to sending data, you must use a POST request

ℹ️ HTTP requests all contain a header. This is the header of the request providing a set of elements, in particular, what is passed in the URL such as the params in the URL, such as the id or the query params which are passed at the end URL after a “?”.

Some HTTP requests may contain a body, the body of the request is used to send data to the server. We find the body in the POST, PUT, and PATCH requests

To retrieve the data passed in the POST request, we need to add a middleware to our Node JS API so that it is able to interpret the request body. This middleware will place itself between the arrival of the request and our routes and execute its code, making it possible to access the body.

Here is our index.js :

const express = require('express')
const app = express()
const parking = require('./parking.json')

// Middleware
app.use(express.json())

app.get('/parking', (req,res) => {
    res.status(200).json(parking)
})

app.get('/parking/:id', (req,res) => {
    const id = parseInt(req.params.id)
    const parking = parking.find(parking => parking.id === id)
    res.status(200).json(parking)
})

app.listen(8080, () => {
    console.log("Server Listening")
})

Now, we just have to add the POST route and test our new route:

const express = require('express')
const app = express()
const parking = require('./parking.json')

// Middleware
app.use(express.json())

app.get('/parkings', (req,res) => {
    res.status(200).json(parking)
})

app.get('/parking/:id', (req,res) => {
    const id = parseInt(req.params.id)
    const parking = parking.find(parking => parking.id === id)
    res.status(200).json(parking)
})

app.post('/parkings', (req,res) => {
    parking.push(req.body)
    res.status(200).json(parking)
})

app.listen(8080, () => {
    console.log("Server Listening")
})

To test our POST route, we are going to use the Postman tool which allows us to easily manipulate APIs.

Our POST request on the URL localhost:8080/parkings contains in its body a JSON object containing the id, name, type, and city of our new parking lot.

In a real case of Node JS API, your database would have generated the id. In our case, we are going to pass it by hand for simplicity.

node-js-api-postman
The creation of a new car park via our Node JS API

Let’s go to the PUT route /parkings/:id to be able to modify a parking lot.

app.put('/parking/:id', (req,res) => {
    const id = parseInt(req.params.id)
    let parking = parking.find(parking => parking.id === id)
    parking.name =req.body.name,
    parking.city =req.body.city,
    parking.type =req.body.type,
    res.status(200).json(parking)
})

Here is the code corresponding to the PUT route. I’ll let you guess where to put it in the index.js file.

ℹ️ To modify a document in a Node JS API, the PUT or PATCH methods are preferred. A PUT request will modify the entire document with the values ​​of the newcomer. A PATCH request will only update certain fields of the document.

We are now left with the route ` DELETE /parkings`

app.delete('/parkings/:id', (req,res) => {
    const id = parseInt(req.params.id)
    let parking = parkings.find(parking => parking.id === id)
    parkings.splice(parkings.indexOf(parking),1)
    res.status(200).json(parkings)
})

Your Node JS API is now able to manage the Parking resource. To implement the Reservation sub-resource, the logic must be replicated.

Your turn to play!

To prepare the data for your Node JS API, here is the reservations.json to place at the root of your project.

For the rest of the realization of your Node JS API, it’s your turn to play. This time, the Reservation resources depend on the Parking resource. For example, the GET route /parkings/1/reservations will retrieve all the reservations for car park 1.

Newsletter SubscriptionYou don't wanna miss our exclusive guides

Get Exclusive Online Business Guides and Tips That I Only Share With Email Subscribers


Spread the love