Stage 3 · Build
HTTP & REST APIs
REST Resource Design
Model resources, collections, filters, PUT versus PATCH, and consistent problem responses.
Resource Modeling
REST is resource-oriented. Every entity in your system maps to a resource with a URL. The URL structure should reflect the data model, not the implementation. Resources are nouns, not verbs.
GET /users → List users
POST /users → Create a user
GET /users/:id → Get a user
PUT /users/:id → Replace a user
PATCH /users/:id → Partially update a user
DELETE /users/:id → Delete a user
GET /users/:id/orders → List a user's orders
POST /users/:id/orders → Create an order for a userNouns, not verbs. Use plural names for collections. Nest related resources to show ownership, but keep nesting shallow (max 2 levels).
Avoid deep nesting like /users/:id/orders/:orderId/items/:itemId. Instead, use /orders/:orderId for direct access. Deep nesting creates URL parsing complexity and coupling.
Collection Patterns
Collections return arrays with metadata about pagination, total count, and links. Never return a raw array without context. Clients need to know if more results exist.
{
"data": [
{"id": "u1", "name": "Alice"},
{"id": "u2", "name": "Bob"}
],
"pagination": {
"total": 142,
"limit": 20,
"offset": 0,
"has_more": true
}
}The data array holds the results. The pagination object tells the client how many total results exist and whether to fetch more.
PUT vs PATCH
PUT replaces the entire resource. PATCH applies a partial update. Clients must send all fields with PUT, but only the changed fields with PATCH. Choose based on your use case.
Filtering
Allow clients to filter collections using query parameters. Keep filter syntax simple and consistent. Avoid complex query languages that are hard to document and debug.
GET /users?status=active&role=admin
GET /users?created_after=2024-01-01
GET /users?search=alice
GET /users?sort=created_at&order=desc
GET /users?limit=20&cursor=abc123Use simple key=value filters. For dates, use ISO 8601 format. For full-text search, use a search parameter. For sorting, use sort and order parameters.
Problem Responses
Every error response should follow a consistent structure. The RFC 7807 Problem Details standard defines a format for HTTP API errors. Use it or define your own consistent format.
{
"type": "https://api.example.com/errors/validation",
"title": "Validation Failed",
"status": 422,
"detail": "The request body contains invalid fields",
"instance": "/users/u1",
"errors": [
{"field": "email", "message": "must be a valid email"},
{"field": "name", "message": "is required"}
]
}Include a type URI, human-readable title, HTTP status, detail message, and the request instance. The type field lets clients link to documentation.
Resource Relationships
Model relationships with nested or linked resources. Use compound keys for many-to-many. Keep relationship endpoints simple and consistent.
Every response should have the same top-level structure. Use { data: ..., meta: ... } for success and { error: ..., code: ..., details: ... } for errors. Clients can parse responses without checking the status code first.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.