Building a REST API with Express.js

Introduction

In the world of web development, creating APIs is a fundamental skill for building dynamic applications. One of the most popular and efficient ways to build a web API is by using Express.js, a lightweight framework built on top of Node.js. Express simplifies the process of routing, handling HTTP requests, and sending responses. It is widely used for creating RESTful APIs due to its simplicity and flexibility.

In this post, we will focus on building a RESTful API using Express.js. You will learn the principles of REST (Representational State Transfer), how to set up routes for handling CRUD operations (Create, Read, Update, Delete), and how to use JSON responses for interacting with clients.


1. What is REST?

REST is an architectural style for designing networked applications. It uses a set of principles and constraints to create APIs that are simple, scalable, and stateless. RESTful APIs are commonly used to enable communication between a client (e.g., a web browser or mobile app) and a server.

Some key principles of REST include:

  • Statelessness: Each request from the client to the server must contain all the information needed to understand and process the request. The server does not store any state between requests.
  • Client-Server Architecture: The client and server are separate entities that communicate over HTTP. The client is responsible for the user interface, and the server handles the data and business logic.
  • Uniform Interface: The API should follow a consistent structure, making it easy to understand and use.
  • Resource-Based: RESTful APIs interact with resources, which are typically represented by URLs. Each resource is identified by a unique URL.

2. Setting Up Express.js

Before we start building our REST API, let’s set up an Express application. If you haven’t already, you’ll need to install Express.

2.1. Installing Express

To begin, create a new directory for your project and initialize a Node.js project:

mkdir express-rest-api
cd express-rest-api
npm init -y

Now, install Express:

npm install express

2.2. Creating a Basic Express Server

Create a file called app.js to set up your basic server:

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

// Middleware to parse JSON data from request bodies
app.use(express.json());

// A basic route to test the server
app.get('/', (req, res) => {
  res.send('Hello, REST API!');
});

// Start the server
app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

Run your server:

node app.js

This will start the server at http://localhost:3000. Now, you’re ready to build your REST API!


3. Principles of RESTful API Design

In RESTful APIs, we typically map HTTP methods to the standard CRUD operations:

  • GET: Retrieve data from the server (Read).
  • POST: Send data to the server to create a new resource (Create).
  • PUT/PATCH: Update an existing resource (Update).
  • DELETE: Remove a resource (Delete).

We will now implement these operations in our API.


4. Defining Routes for CRUD Operations

Let’s create a simple API for managing a list of users. Each user will have an id, name, and email.

4.1. Create a New User (POST)

We will start by implementing the POST method to create a new user. Here’s how we can set up the route:

let users = [
  { id: 1, name: 'John Doe', email: '[email protected]' },
  { id: 2, name: 'Jane Doe', email: '[email protected]' }
];

// POST - Create a new user
app.post('/users', (req, res) => {
  const { name, email } = req.body;

  if (!name || !email) {
return res.status(400).json({ message: 'Name and email are required' });
} const newUser = {
id: users.length + 1,
name,
email
}; users.push(newUser); res.status(201).json(newUser); // Respond with the newly created user });
  • When a POST request is made to /users, we extract the name and email from the request body.
  • If the data is missing, we return a 400 Bad Request error.
  • If the data is valid, we create a new user and add it to our users array. The server responds with a 201 Created status and the newly created user data.

4.2. Get All Users (GET)

Next, let’s implement the GET method to retrieve all users:

// GET - Get all users
app.get('/users', (req, res) => {
  res.status(200).json(users); // Respond with all users
});
  • When a GET request is made to /users, the server responds with the list of all users in the users array.

4.3. Get a Single User by ID (GET)

We can also add functionality to get a single user by their unique id:

// GET - Get a user by ID
app.get('/users/:id', (req, res) => {
  const userId = parseInt(req.params.id, 10);
  const user = users.find(u => u.id === userId);

  if (!user) {
return res.status(404).json({ message: 'User not found' });
} res.status(200).json(user); // Respond with the user data });
  • In this case, the GET request is made with a dynamic parameter (/users/:id), which is the id of the user to retrieve.
  • We search the users array for a user with the specified id. If the user is found, we return their data. If not, we return a 404 Not Found error.

4.4. Update an Existing User (PUT)

To update an existing user, we will use the PUT method. This allows us to modify a user’s data:

// PUT - Update an existing user
app.put('/users/:id', (req, res) => {
  const userId = parseInt(req.params.id, 10);
  const { name, email } = req.body;

  const userIndex = users.findIndex(u => u.id === userId);

  if (userIndex === -1) {
return res.status(404).json({ message: 'User not found' });
} if (!name || !email) {
return res.status(400).json({ message: 'Name and email are required' });
} // Update the user data users[userIndex] = { id: userId, name, email }; res.status(200).json(users[userIndex]); // Respond with the updated user });
  • When a PUT request is made to /users/:id, we check if the user exists. If they do, we update their name and email based on the request body, and then return the updated user data. If the user doesn’t exist, we return a 404 Not Found error.

4.5. Delete a User (DELETE)

Finally, let’s implement the DELETE method to remove a user from the list:

// DELETE - Delete a user
app.delete('/users/:id', (req, res) => {
  const userId = parseInt(req.params.id, 10);
  const userIndex = users.findIndex(u => u.id === userId);

  if (userIndex === -1) {
return res.status(404).json({ message: 'User not found' });
} // Remove the user from the array users.splice(userIndex, 1); res.status(204).send(); // Respond with no content (successful deletion) });
  • When a DELETE request is made to /users/:id, we check if the user exists in the users array. If the user is found, we remove them and return a 204 No Content status to indicate successful deletion. If the user is not found, we return a 404 Not Found error.

5. Full Example of the REST API

Here’s the full code combining all the CRUD operations for the users API:

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

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

let users = [
  { id: 1, name: 'John Doe', email: '[email protected]' },
  { id: 2, name: 'Jane Doe', email: '[email protected]' }
];

// POST - Create a new user
app.post('/users', (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) {
return res.status(400).json({ message: 'Name and email are required' });
} const newUser = { id: users.length + 1, name, email }; users.push(newUser); res.status(201).json(newUser); }); // GET - Get all users app.get('/users', (req,

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *