REST API Design
A practical primer on designing predictable, scalable HTTP APIs that your future self will thank you for.
Resources, not verbs
Model your API around nouns — /users, /orders, /sessions. Let HTTP methods carry the action. A clean URL tells the story before you read a single line of docs.
Method semantics
- GET — idempotent, safe, never mutates state. Cache aggressively.
- POST — creates a new resource. Return
201 Createdwith aLocationheader. - PUT — full replacement. Idempotent. Client sends the entire representation.
- PATCH — partial update. Use JSON Merge Patch or JSON Patch; document which.
- DELETE — idempotent. Return
204 No Contentor200with the deleted entity.
Status codes that mean something
Don't shove every error into 400 or 500. Use 401 for missing auth, 403 for insufficient permissions, 409 for version conflicts, and 422 for validation failures. Clients can branch logic on status alone.
Versioning
Prefer URL-prefix versioning: /v1/users. It's explicit, cache-friendly, and impossible to miss in logs. Avoid header-based versioning unless you have strong CDN constraints.
Pagination from day one
Cursor-based pagination with ?after= and ?limit= scales better than offset. Always return a next cursor in the response envelope so clients never need to count.
Consistent envelope
Wrap every response in a predictable shape: { data, error, meta }. Single-record responses still go in data. This eliminates type-ambiguity on the client and makes middleware trivial.
Next recipe
Authentication patterns →