Back to docs
Recipe

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 Created with a Location header.
  • 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 Content or 200 with 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.