What is REST?
REST (Representational State Transfer) is an architectural style for designing networked applications. It uses standard HTTP methods and status codes, making APIs intuitive for developers who understand HTTP.
A RESTful API treats data as "resources" accessed via URLs, manipulated using HTTP methods (GET, POST, PUT, DELETE). Good REST design creates APIs that are predictable, consistent, and easy to use.
Resource Naming
URLs should identify resources (nouns), not actions (verbs). The HTTP method indicates the action.
/getUsers /createUser /deleteUser/123 /getUserOrders
GET /users POST /users DELETE /users/123 GET /users/123/orders
Naming Conventions
- Plural nouns:
/usersnot/user - Lowercase:
/usersnot/Users - Hyphens for readability:
/user-profilesnot/userProfiles - No trailing slashes:
/usersnot/users/ - No file extensions:
/usersnot/users.json
HTTP Methods
| Method | Purpose | Idempotent | Safe |
|---|---|---|---|
| GET | Retrieve resources | Yes | Yes |
| POST | Create new resources | No | No |
| PUT | Replace entire resource | Yes | No |
| PATCH | Partial update | No* | No |
| DELETE | Remove resource | Yes | No |
*PATCH can be idempotent depending on implementation.
Example CRUD Operations
GET /users # List all users GET /users/123 # Get user 123 POST /users # Create new user PUT /users/123 # Replace user 123 entirely PATCH /users/123 # Update specific fields of user 123 DELETE /users/123 # Delete user 123
Request and Response Format
Consistent JSON Structure
// Single resource
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-15T10:30:00Z"
}
// Collection
{
"data": [
{ "id": 1, "name": "John Doe" },
{ "id": 2, "name": "Jane Smith" }
],
"meta": {
"total": 100,
"page": 1,
"per_page": 20
}
}
Error Responses
{
"error": {
"code": "validation_error",
"message": "The request data is invalid",
"details": {
"email": ["Invalid email format"],
"password": ["Must be at least 8 characters"]
}
}
}
Status Codes
// Success 200 OK # Successful GET, PUT, PATCH 201 Created # Successful POST (include Location header) 204 No Content # Successful DELETE // Client Errors 400 Bad Request # Malformed request 401 Unauthorized # Missing or invalid authentication 403 Forbidden # Authenticated but not authorized 404 Not Found # Resource doesn't exist 422 Unprocessable # Validation errors // Server Errors 500 Internal Server Error # Unexpected error
Filtering, Sorting, and Pagination
Filtering
GET /users?status=active GET /users?role=admin&status=active GET /orders?created_after=2024-01-01 GET /products?price_min=10&price_max=100
Sorting
GET /users?sort=created_at # Ascending GET /users?sort=-created_at # Descending (prefix with -) GET /users?sort=name,-created_at # Multiple fields
Pagination
// Page-based
GET /users?page=2&per_page=20
// Cursor-based (better for large datasets)
GET /users?cursor=abc123&limit=20
// Response includes pagination meta
{
"data": [...],
"meta": {
"total": 1000,
"page": 2,
"per_page": 20,
"total_pages": 50
},
"links": {
"first": "/users?page=1",
"prev": "/users?page=1",
"next": "/users?page=3",
"last": "/users?page=50"
}
}
Nested Resources
Express relationships through URL structure:
GET /users/123/orders # Orders belonging to user 123 GET /users/123/orders/456 # Specific order of user 123 POST /users/123/orders # Create order for user 123 GET /posts/123/comments # Comments on post 123 POST /posts/123/comments # Add comment to post 123
Guidelines
- Limit nesting to 2-3 levels maximum
- If resources can exist independently, don't nest
- Use query parameters for optional relationships
API Versioning
URL Path (Most Common)
/api/v1/users /api/v2/users
Header-based
Accept: application/vnd.api+json; version=1
Query Parameter
/api/users?version=1
URL versioning is most visible and commonly used. Version when making breaking changes (removing fields, changing response structure).
Authentication
Bearer Tokens (JWT)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
API Keys
// Header X-API-Key: your-api-key // Query parameter (less secure, visible in logs) /api/users?api_key=your-api-key
Best Practices
- Always use HTTPS
- Prefer headers over query parameters for credentials
- Implement rate limiting
- Use short-lived access tokens with refresh tokens
HATEOAS
Hypermedia as the Engine of Application State—include links to related resources and available actions:
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"_links": {
"self": { "href": "/users/123" },
"orders": { "href": "/users/123/orders" },
"update": { "href": "/users/123", "method": "PATCH" },
"delete": { "href": "/users/123", "method": "DELETE" }
}
}
HATEOAS makes APIs more discoverable but adds complexity. It's optional for most APIs.
Documentation
Good documentation is essential. Include:
- Authentication methods
- All endpoints with HTTP methods
- Request/response examples
- Error codes and messages
- Rate limits
- Changelog
Tools like OpenAPI (Swagger) can generate interactive documentation from your API specification.
Best Practices Summary
- Use nouns for URLs, HTTP methods for actions
- Return appropriate status codes
- Use consistent JSON response structure
- Version your API from the start
- Implement pagination for list endpoints
- Support filtering and sorting
- Always use HTTPS
- Provide comprehensive documentation
- Return helpful error messages
- Implement rate limiting
Format API Responses
Use our JSON formatter to beautify and validate your API response payloads.
Open JSON Formatter →