RESTful Design Principles
RESTful Design Principles
A well-designed REST API is predictable, consistent, and easy to use. These principles separate amateur APIs from professional ones.
Resources, Not Actions
Think in terms of resources (nouns), not actions (verbs). The HTTP method provides the action. Bad: POST /getProducts. Good: GET /products.
GET /api/products # List all products
GET /api/products/42 # Get product 42
POST /api/products # Create a new product
PUT /api/products/42 # Replace product 42
PATCH /api/products/42 # Partially update product 42
DELETE /api/products/42 # Delete product 42
GET /api/products/42/reviews # List reviews for product 42
POST /api/products/42/reviews # Add a review to product 42
Nesting for Relationships
Use nested resources for relationships. /products/42/reviews clearly shows reviews belong to product 42. Keep nesting to two levels maximum - deeper nesting becomes unwieldy.
Meaningful HTTP Status Codes
Status codes tell the client what happened without reading the body:
200 OK # Successful GET, PUT, PATCH
201 Created # Successful POST
204 No Content # Successful DELETE
400 Bad Request # Invalid input
401 Unauthorized # Authentication required
403 Forbidden # Authenticated but not authorized
404 Not Found # Resource does not exist
409 Conflict # Duplicate or state conflict
422 Unprocessable # Valid syntax but business rules failed
500 Server Error # Unexpected failure
Consistent Response Shapes
Use the same JSON structure across all endpoints. Wrapping responses in a consistent envelope helps clients:
{"data": [...], "total": 42, "page": 1, "size": 20}
{"error": "Not found", "status": 404}
Idempotency
GET, PUT, and DELETE should be idempotent - calling them multiple times has the same effect as calling once. POST is the exception; it creates a new resource each time.
Key Points
- Resources are nouns; HTTP methods are the verbs.
- Use nested routes for relationships, max two levels deep.
- Return appropriate HTTP status codes for every response.
- Keep response JSON structure consistent across all endpoints.
- GET, PUT, and DELETE should be idempotent.