Building RESTful APIs with Node.js and Express: Step-by-Step Tutorial

Ashish prajapati - Oct 19 - - Dev Community

Building RESTful APIs with Node.js and Express

A RESTful API (Representational State Transfer) is a popular architectural style for building web services, where the client (frontend) interacts with the server (backend) using HTTP requests. RESTful APIs are lightweight, stateless, and scalable, making them ideal for modern applications.

Node.js is a runtime environment that allows JavaScript to be run on the server side. Combined with Express, a minimal and flexible web application framework for Node.js, you can easily create powerful RESTful APIs.

Here’s a step-by-step explanation of how to build a RESTful API with Node.js and Express:


1. Setup Node.js and Express

Step 1: Install Node.js

To begin, make sure Node.js is installed on your system. You can download it from the official website. Once installed, initialize a new project:

mkdir rest-api
cd rest-api
npm init -y
Enter fullscreen mode Exit fullscreen mode

This creates a basic package.json file that keeps track of the project dependencies.

Step 2: Install Express

Next, install Express using npm (Node Package Manager):

npm install express
Enter fullscreen mode Exit fullscreen mode

2. Basic Server Setup

Now, create a basic server using Express. In the root of your project, create a file called app.js:

// app.js

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

app.use(express.json()); // Middleware to parse JSON requests

app.get('/', (req, res) => {
  res.send('Welcome to the REST API!');
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Run the server by executing:

node app.js
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000 in your browser, and you should see "Welcome to the REST API!"


3. Define API Endpoints (CRUD Operations)

Let’s build the core functionality of a RESTful API, focusing on CRUD operations (Create, Read, Update, Delete) for a sample resource, such as users.

  1. GET Request (Read All Users)
app.get('/users', (req, res) => {
  const users = [
    { id: 1, name: 'Name1' },
    { id: 2, name: 'Name2' },
  ];
  res.json(users);
});
Enter fullscreen mode Exit fullscreen mode

This endpoint will respond with a list of users in JSON format when the client sends a GET request to /users.

  1. GET Request (Read Single User)
app.get('/users/:id', (req, res) => {
  const users = [
    { id: 1, name: 'Name1' },
    { id: 2, name: 'Name2' },
  ];
  const user = users.find((u) => u.id === parseInt(req.params.id));
  if (user) {
    res.json(user);
  } else {
    res.status(404).send('User not found');
  }
});
Enter fullscreen mode Exit fullscreen mode

The :id in the route allows dynamic values, where the client can specify which user they want to retrieve by ID.

  1. POST Request (Create a User)
app.post('/users', (req, res) => {
  const newUser = {
    id: Date.now(),
    name: req.body.name,
  };
  // Normally, you would save this user to a database
  res.status(201).json(newUser);
});
Enter fullscreen mode Exit fullscreen mode

The POST method allows clients to send data (usually via JSON) to create new resources. Here, req.body captures the data sent from the client, and a new user object is created and returned.

  1. PUT Request (Update a User)
app.put('/users/:id', (req, res) => {
  const users = [
    { id: 1, name: 'Name1' },
    { id: 2, name: 'Name2' },
  ];
  const user = users.find((u) => u.id === parseInt(req.params.id));
  if (user) {
    user.name = req.body.name;
    res.json(user);
  } else {
    res.status(404).send('User not found');
  }
});
Enter fullscreen mode Exit fullscreen mode

The PUT method allows the client to update an existing resource. The server finds the user by ID and updates the name based on the client’s input.

  1. DELETE Request (Delete a User)
app.delete('/users/:id', (req, res) => {
  const users = [
    { id: 1, name: 'Name1' },
    { id: 2, name: 'Name2' },
  ];
  const userIndex = users.findIndex((u) => u.id === parseInt(req.params.id));
  if (userIndex !== -1) {
    users.splice(userIndex, 1); // Remove the user from the array
    res.send('User deleted');
  } else {
    res.status(404).send('User not found');
  }
});
Enter fullscreen mode Exit fullscreen mode

The DELETE method removes a specific resource. In this case, it deletes a user based on the ID passed in the URL.


4. Using a Database

To persist data, you can integrate a database like MongoDB or MySQL. For example, to use MongoDB with Node.js, you would install the Mongoose library and connect your API to a database:

npm install mongoose
Enter fullscreen mode Exit fullscreen mode

Then, modify your code to use Mongoose for handling CRUD operations on a database rather than in-memory data:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true });
Enter fullscreen mode Exit fullscreen mode

5. Error Handling and Status Codes

It's important to handle errors properly in your API and return appropriate HTTP status codes:

  • 200 OK for successful requests
  • 201 Created for resource creation
  • 400 Bad Request for invalid inputs
  • 404 Not Found when a resource does not exist
  • 500 Internal Server Error for unexpected failures

Example of error handling:

app.get('/users/:id', (req, res) => {
  try {
    const user = users.find((u) => u.id === parseInt(req.params.id));
    if (!user) throw new Error('User not found');
    res.json(user);
  } catch (error) {
    res.status(404).json({ message: error.message });
  }
});
Enter fullscreen mode Exit fullscreen mode

6. Testing the API

You can test the API using tools like Postman or curl by sending HTTP requests to the various endpoints.

Example curl command for testing the POST endpoint:

curl -X POST http://localhost:3000/users -H "Content-Type: application/json" -d '{"name": "User"}'
Enter fullscreen mode Exit fullscreen mode

Conclusion

Building a RESTful API with Node.js and Express is relatively simple and efficient. By following these steps, you can set up routes, handle HTTP requests, and integrate with databases to create a full-fledged API. You can further enhance the API by adding features like authentication, validation, and logging to make it production-ready.

. . . . . . . . . . . . . . . . . . . . . . . .