
REST API Design: Best Practices and Standards
Md Nayeem Hossain
Author
Md Nayeem Hossain
Author
REST API Design Best Practices
An API is a product for developers. If it's hard to use or inconsistent, developers will hate integrating with it. Good API design is intuitive, predictable, and self-documenting.
Resource Naming
Use nouns, not verbs. The HTTP method tells you the verb.
Bad:
POST /createNewUser
GET /getAllUsers
Good:
POST /users (Create)
GET /users (List)
GET /users/123 (Retrieve 123)
PUT /users/123 (Update 123)
DELETE /users/123 (Delete 123)Using Proper HTTP Status Codes
Don't just return 200 OK for everything. Use the standard codes to communicate what happened.
Validation with Zod
Never trust client input. Validation should be the first thing your API does. I recommend using Zod for schema validation in Node.js. It's type-safe and declarative.
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
role: z.enum(['admin', 'user']).default('user'),
});
app.post('/users', (req, res) => {
// Unsafe input
const result = CreateUserSchema.safeParse(req.body);
if (!result.success) {
// Automatically returns a detailed list of what fields were wrong
return res.status(400).json(result.error);
}
// Safe, typed data
const data = result.data;
// ... create user
});Pagination
Never return "all" records. Your database might have 10,000 users one day. Always implement pagination.
// GET /users?page=2&limit=20
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 20;
const skip = (page - 1) * limit;
const users = await db.user.findMany({ skip, take: limit });
res.json({
data: users,
meta: {
page,
limit,
total: await db.user.count()
}
});Providing metadata (total pages, current page) helps the frontend build pagination UI easily.


