On this page
REST API Design
A REST API uses HTTP methods and URLs to perform CRUD operations on resources.
REST Conventions
| Method | URL | Action |
|---|---|---|
| GET | /api/users |
List users |
| GET | /api/users/1 |
Get user by ID |
| POST | /api/users |
Create user |
| PUT | /api/users/1 |
Replace user |
| PATCH | /api/users/1 |
Partial update |
| DELETE | /api/users/1 |
Delete user |
Complete CRUD Example
import express from 'express';
const app = express();
app.use(express.json());
let users = [
{ id: 1, name: 'Alice', email: '[email protected]' },
{ id: 2, name: 'Bob', email: '[email protected]' }
];
// List all
app.get('/api/users', (req, res) => {
res.json(users);
});
// Get one
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === Number(req.params.id));
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
// Create
app.post('/api/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email required' });
}
const user = { id: Date.now(), name, email };
users.push(user);
res.status(201).json(user);
});
// Update
app.put('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === Number(req.params.id));
if (index === -1) return res.status(404).json({ error: 'Not found' });
users[index] = { ...users[index], ...req.body, id: users[index].id };
res.json(users[index]);
});
// Delete
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === Number(req.params.id));
if (index === -1) return res.status(404).json({ error: 'Not found' });
users.splice(index, 1);
res.status(204).send();
});
Pagination
app.get('/api/users', (req, res) => {
const page = Math.max(1, Number(req.query.page) || 1);
const limit = Math.min(100, Number(req.query.limit) || 10);
const start = (page - 1) * limit;
const paginated = users.slice(start, start + limit);
res.json({
data: paginated,
pagination: {
page,
limit,
total: users.length,
totalPages: Math.ceil(users.length / limit)
}
});
});
Consistent Response Format
// Success
{ "data": { ... }, "message": "User created" }
// Error
{ "error": "Validation failed", "details": ["Email is required"] }
API Versioning
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
Input Validation with express-validator
npm install express-validator
import { body, validationResult } from 'express-validator';
app.post('/api/users',
body('email').isEmail(),
body('name').trim().notEmpty(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Create user...
}
);
Follow REST conventions for predictable, maintainable APIs that front-end and mobile clients can rely on.