Back to Blog

REST API Design Made Simple with Express.js

4 min readBackend, APIs, Express

What is a REST API?

Think of an API (Application Programming Interface) as a waiter in a restaurant. You (the client, like a web browser or mobile app) look at the menu and tell the waiter what you want. The waiter takes your request to the kitchen (the server), and then brings the food (the data) back to you.

A REST (Representational State Transfer) API is simply a set of rules for this communication. It uses standard web protocols (HTTP) to make requests and receive responses, usually in JSON format.

The History: Before REST

Before REST (introduced by Roy Fielding in 2000) became the industry standard, web services typically relied on protocols like SOAP or RPC (Remote Procedure Call). In those early days, the URL used to contain the complete route and action information.

Developers had to build entirely unique endpoints for every single operation—such as /getUserDetails?id=1, /createNewUser, or /deleteUser. REST revolutionized this architecture by moving the action to the HTTP method (GET, POST, DELETE) and keeping the URL strictly for identifying the resource (/users/1).

Resources: The Heart of REST

In REST architecture, everything revolves around resources. A resource is any object or data your API manages.

Golden Rule: Resources should always be named as plural nouns, never verbs. The action you want to perform is defined by the HTTP method, not the URL.

  • Bad: /getUsers, /createNewUser, /deleteUser/1
  • Good: /users, /users/1

Mapping CRUD to HTTP Methods

To interact with our resources, we map standard CRUD (Create, Read, Update, Delete) database operations to specific HTTP methods.

Here is how that mapping works for our /users resource:

CRUD OperationHTTP MethodRoute ExampleWhat it does
CreatePOST/usersCreates a new user.
ReadGET/usersRetrieves a list of all users.
ReadGET/users/:idRetrieves a specific user by their ID.
UpdatePUT/users/:idUpdates or replaces a specific user completely.
DeleteDELETE/users/:idDeletes a specific user.

(Note: PATCH is also used for partial updates, while PUT is typically for full replacements).

Status Codes Made Simple

When the server responds, it sends a three-digit HTTP status code to let the client know how the request went.

  • 2xx (Success)
    • 200 OK: The request succeeded (standard for GET and PUT).
    • 201 Created: A new resource was successfully created (standard for POST).
    • 204 No Content: The request succeeded, but there is no data to send back (standard for DELETE).
  • 4xx (Client Error - You messed up)
    • 400 Bad Request: The request was invalid or missing data.
    • 404 Not Found: The requested resource (e.g., user ID) does not exist.
  • 5xx (Server Error - We messed up)
    • 500 Internal Server Error: Something broke on the server side.

Designing Routes in Express.js

Here is how these principles look when translated into clean Express.js code for our users resource:

const express = require('express');
const app = express();
app.use(express.json());

// READ: Get all users
app.get('/users', (req, res) => {
    res.status(200).json({ message: "List of all users" });
});

// READ: Get a specific user by ID
app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.status(200).json({ message: `Details for user ${userId}` });
});

// CREATE: Add a new user
app.post('/users', (req, res) => {
    const newUser = req.body;
    res.status(201).json({ message: "User created successfully", user: newUser });
});

// UPDATE: Replace user data
app.put('/users/:id', (req, res) => {
    const userId = req.params.id;
    const updatedData = req.body;
    res.status(200).json({ message: `User ${userId} updated` });
});

// DELETE: Remove a user
app.delete('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.status(204).send();
});

app.listen(3000, () => console.log('API running on port 3000'));
'''

This is all for REST APIs. Happy Coding!!