RESTful API Design
Learn RESTful API design principles and best practices for building scalable APIs
60 minโขBy Priygop TeamโขLast updated: Feb 2026
REST API Principles
REST (Representational State Transfer) is an architectural style for designing networked applications. RESTful APIs use HTTP methods to perform CRUD operations on resources and follow specific conventions for URL structure and response formats.
RESTful API Implementation
Example
// RESTful API structure
const express = require('express');
const router = express.Router();
// GET /api/users - Get all users
router.get('/users', async (req, res) => {
try {
const users = await User.find();
res.json({
success: true,
data: users,
count: users.length
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Failed to fetch users'
});
}
});
// GET /api/users/:id - Get user by ID
router.get('/users/:id', async (req, res) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
res.json({
success: true,
data: user
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Failed to fetch user'
});
}
});
// POST /api/users - Create new user
router.post('/users', async (req, res) => {
try {
const user = new User(req.body);
const savedUser = await user.save();
res.status(201).json({
success: true,
data: savedUser
});
} catch (error) {
res.status(400).json({
success: false,
error: 'Failed to create user'
});
}
});
// PUT /api/users/:id - Update user
router.put('/users/:id', async (req, res) => {
try {
const user = await User.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true, runValidators: true }
);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
res.json({
success: true,
data: user
});
} catch (error) {
res.status(400).json({
success: false,
error: 'Failed to update user'
});
}
});
// DELETE /api/users/:id - Delete user
router.delete('/users/:id', async (req, res) => {
try {
const user = await User.findByIdAndDelete(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
res.json({
success: true,
message: 'User deleted successfully'
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Failed to delete user'
});
}
});
// Query parameters and pagination
router.get('/users', async (req, res) => {
try {
const { page = 1, limit = 10, sort = 'createdAt', order = 'desc' } = req.query;
const skip = (page - 1) * limit;
const sortOrder = order === 'desc' ? -1 : 1;
const users = await User.find()
.sort({ [sort]: sortOrder })
.limit(parseInt(limit))
.skip(skip);
const total = await User.countDocuments();
res.json({
success: true,
data: users,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total,
pages: Math.ceil(total / limit)
}
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Failed to fetch users'
});
}
});