REST API Design: Best Practices That Actually Matter
Most API design guides focus on REST purity. This guide focuses on what actually matters in production.
Use HTTP Methods Correctly
This isn't about REST purity. It's about predictability:
GET /users - List users
GET /users/123 - Get specific user
POST /users - Create user
PUT /users/123 - Update user (full)
PATCH /users/123 - Update user (partial)
DELETE /users/123 - Delete user
Stick to this pattern. Don't be clever.
Always Version Your API
From day one:
/api/v1/users
Changing APIs without versions breaks clients. Version from the start.
Use Consistent Response Formats
Pick a format and stick to it:
{
"data": {...},
"error": null,
"meta": {
"timestamp": "2025-12-12T10:00:00Z"
}
}
Consistency matters more than the specific format you choose.
Handle Errors Properly
Return proper HTTP status codes:
- 200: Success
- 201: Created
- 400: Bad request (client error)
- 401: Unauthorized
- 404: Not found
- 500: Server error
And include helpful error messages:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"field": "email"
}
}
Pagination is Not Optional
Don't return 10,000 records. Always paginate:
GET /users?page=2&limit=20
Return pagination metadata:
{
"data": [...],
"meta": {
"page": 2,
"limit": 20,
"total": 500,
"hasMore": true
}
}
Use Query Parameters for Filtering
GET /users?role=admin&status=active&sort=-createdAt
Clean, predictable, and works with HTTP caching.
Authentication Done Right
Use Bearer tokens in headers:
Authorization: Bearer <token>
Don't put auth tokens in URLs. They get logged everywhere.
Rate Limiting is Essential
Protect your API:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640000000
Return 429 (Too Many Requests) when exceeded.
Documentation is Not Optional
Use OpenAPI/Swagger. Auto-generate docs from code when possible.
No one will use your API if they can't figure it out.
Key Takeaways
- Be consistent above all else
- Version from day one
- Handle errors properly
- Always paginate
- Document everything
- Rate limit everything
Good API design is boring. That's the point. Boring is predictable. Predictable is good.