REST API Design Made Simple with Express.js

Software Engineer | Passionate about Web Development, DSA & Problem Solving. I write simple, practical tech blogs to help developers learn and grow. Exploring JavaScript, C++, Backend & Modern Web Technologies.
Introduction
In modern web development, applications rarely operate in isolation. Whether it’s a frontend React application fetching user data, a mobile app displaying products, or a third-party service integrating with your platform, communication between systems is essential. This communication is made possible through APIs (Application Programming Interfaces), and among all API styles, REST APIs have become the industry standard due to their simplicity, scalability, and clarity.
A well-designed REST API acts like a well-organized contract between a client and a server. It defines how requests are made, how data is structured, and how responses are returned. Poor API design, on the other hand, leads to confusion, inconsistent behavior, and difficult maintenance as applications grow.
Express.js, a lightweight and flexible Node.js framework, makes building REST APIs straightforward and efficient. It provides a clean way to define routes, handle HTTP methods, and structure backend logic. Understanding REST principles while using Express ensures that your APIs are not only functional but also intuitive and scalable.
In this blog, we will break down REST API design step by step, focusing on a single resource—users—to build a strong conceptual foundation that is both beginner-friendly and interview-ready.
What REST API Means
REST (Representational State Transfer) is an architectural style used for designing networked applications. A REST API allows a client (like a browser or mobile app) to communicate with a server using standard HTTP methods.
At its core, REST treats everything as a resource, and each resource is accessed using a unique URL.
A REST API follows these principles:
Stateless communication
Resource-based structure
Use of standard HTTP methods
Predictable and consistent endpoints
Example
const express = require('express');
const app = express();
app.get('/hello', (req, res) => {
res.send("Hello from REST API");
});
app.listen(3000);
Explanation :
A simple API endpoint
/hellois created.The client sends a GET request.
The server responds with a message.
This demonstrates basic client-server communication using REST.
Real-World Analogy
Think of an API like a restaurant menu:
Client = Customer
Server = Kitchen
API = Menu
Request = Order
Response = Food served
Resources in REST Architecture
In REST, everything is treated as a resource. A resource can be any entity such as:
Users
Products
Orders
Each resource is represented by a URL.
For example:
/users
/users/101
Here:
/users→ collection of users/users/101→ specific user
Example
app.get('/users', (req, res) => {
res.send("List of users");
});
app.get('/users/:id', (req, res) => {
res.send(`User with ID ${req.params.id}`);
});
Explanation of Code
/usersreturns all users/users/:idreturns a specific user:idacts as a dynamic identifier
Before vs After (Bad vs Good Design)
| Bad Design | Good REST Design |
|---|---|
| /getUsers | /users |
| /getUserById | /users/:id |
HTTP Methods in REST
REST APIs use HTTP methods to define actions on resources.
GET (Read Data)
GET is used to retrieve data.
Example
app.get('/users', (req, res) => {
res.send("Fetching users");
});
Explanation :
Client requests data
Server responds with user list
No data is modified
POST (Create Data)
POST is used to create new resources.
Example
app.post('/users', (req, res) => {
res.send("User created");
});
Explanation :
Client sends data
Server creates a new user
PUT (Update Data)
PUT is used to update an existing resource.
Example
app.put('/users/:id', (req, res) => {
res.send(`User ${req.params.id} updated`);
});
Explanation :
Updates user with given ID
Replaces existing data
DELETE (Remove Data)
DELETE removes a resource.
Example
app.delete('/users/:id', (req, res) => {
res.send(`User ${req.params.id} deleted`);
});
Explanation :
- Deletes the specified user
CRUD vs HTTP Mapping
| Operation | HTTP Method | Endpoint |
|---|---|---|
| Create | POST | /users |
| Read | GET | /users |
| Update | PUT | /users/:id |
| Delete | DELETE | /users/:id |
Status Codes Basics
Status codes indicate the result of an API request.
Common status codes:
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 400 | Bad Request |
| 404 | Not Found |
| 500 | Server Error |
Example
app.get('/users/:id', (req, res) => {
const userExists = false;
if (!userExists) {
return res.status(404).send("User not found");
}
res.status(200).send("User found");
});
Explanation :
If user not found → 404
If found → 200
Status codes provide clarity to client
Before vs After
| Without Status Codes | With Status Codes |
|---|---|
| Confusing responses | Clear communication |
| Hard to debug | Easy debugging |
Designing Routes Using REST Principles
Good API design follows clean and predictable naming conventions.
Rules:
Use nouns, not verbs
Keep URLs simple
Use plural resource names
Example (User Resource)
app.get('/users', (req, res) => {});
app.get('/users/:id', (req, res) => {});
app.post('/users', (req, res) => {});
app.put('/users/:id', (req, res) => {});
app.delete('/users/:id', (req, res) => {});
Explanation of Code
All routes revolve around
/usersHTTP method defines the action
URL defines the resource
REST Request-Response Lifecycle
A REST API follows a structured lifecycle:
Client sends HTTP request
Server processes request
Database interaction happens
Server sends response with status code
Example
app.get('/users', (req, res) => {
const users = ["Aman", "Riya"];
res.status(200).json(users);
});
Explanation of Code
Client requests
/usersServer prepares data
Response is sent in JSON format
Status code indicates success
Conclusion
REST API design is not just about writing routes—it is about creating a structured and predictable system that enables smooth communication between client and server. By treating everything as a resource and using standard HTTP methods, developers can build APIs that are easy to understand, scalable, and maintainable.
Express.js simplifies this process by providing a clean and flexible framework to implement REST principles. From defining routes to handling status codes, it allows developers to focus on logic while maintaining clarity in design.
The key takeaways are simple but powerful: use resources as nouns, rely on HTTP methods for actions, return meaningful status codes, and keep your API consistent. Whether you are preparing for interviews or building production-grade applications, mastering REST API design is an essential skill that will significantly improve the quality of your backend systems.




