// Backend
REST API Design: Best Practices and Standards
Learn how to design clean, intuitive, and scalable REST APIs following industry best practices.
Md Nayeem HossainDec 8, 202412 min read// Backend
Learn how to design clean, intuitive, and scalable REST APIs following industry best practices.
Md Nayeem HossainDec 8, 202412 min read
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.
Use nouns, not verbs. The HTTP method tells you the verb.
1Bad:2POST /createNewUser3GET /getAllUsers4 5Good:6POST /users (Create)7GET /users (List)8GET /users/123 (Retrieve 123)9PUT /users/123 (Update 123)10DELETE /users/123 (Delete 123)Don't just return 200 OK for everything. Use the standard codes to communicate what happened.
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.
1import { z } from 'zod';2 3const CreateUserSchema = z.object({4 name: z.string().min(2),5 email: z.string().email(),6 role: z.enum(['admin', 'user']).default('user'),7});8 9app.post('/users', (req, res) => {10 // Unsafe input11 const result = CreateUserSchema.safeParse(req.body);12 13 if (!result.success) {14 // Automatically returns a detailed list of what fields were wrong15 return res.status(400).json(result.error);16 }17 18 // Safe, typed data19 const data = result.data;20 // ... create user21});Never return "all" records. Your database might have 10,000 users one day. Always implement pagination.
1// GET /users?page=2&limit=202const page = parseInt(req.query.page) || 1;3const limit = parseInt(req.query.limit) || 20;4const skip = (page - 1) * limit;5 6const users = await db.user.findMany({ skip, take: limit });7 8res.json({9 data: users,10 meta: {11 page,12 limit,13 total: await db.user.count()14 }15});Providing metadata (total pages, current page) helps the frontend build pagination UI easily.