REST API Design
Design and build RESTful APIs with proper resource modeling, status codes, versioning, authentication, and OpenAPI documentation.
skill: REST API Design category: Web Development tags: [REST, API Design, HTTP, OpenAPI, Backend] readingTime: 6
REST is the default choice for public APIs and browser clients due to its cacheable, stateless nature and broad tooling support. For type-safe internal APIs consider gRPC. For flexible client-driven queries consider GraphQL. For real-time bidirectional communication consider WebSockets.
Workflow
- Model resources, not actionsREST APIs are noun-based - URLs identify resources; HTTP verbs describe what to do with them. Action-based URLs are an anti-pattern.
- Return correct HTTP status codesStatus codes tell clients how to react - a 200 with an error body defeats HTTP's built-in error handling.
- Version the APIBreaking changes are inevitable. Versioning protects existing clients from being broken by new requirements.
- Authenticate with Bearer tokensStateless Bearer tokens (JWTs or opaque tokens) scale across multiple servers without session stores.
- Document with OpenAPI (Swagger)OpenAPI spec generates interactive docs, client SDKs, and mock servers automatically - one source of truth for the API contract.
Output Format
RESTful API with consistent resource URLs, status codes, authentication, and OpenAPI documentation.
GET /v1/{resources} → 200 + array
GET /v1/{resources}/{id} → 200 + object | 404
POST /v1/{resources} → 201 + object + Location header
PATCH /v1/{resources}/{id} → 200 + updated object
DELETE /v1/{resources}/{id} → 204 no bodyExamples
Input
Output
Input
Output
Edge Cases & Gotchas
- Idempotency for POST - POST is not idempotent by default. Use an Idempotency-Key header to prevent duplicate creation if the client retries on network failure.
- HATEOAS overkill - Full HATEOAS (embedding links in responses) adds complexity without clear client benefit in most cases. Stick to sensible resource URLs and a good OpenAPI doc instead.
- Rate limiting headers - Include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so clients can self-throttle before getting a 429.
- CORS preflight - Browser clients send OPTIONS preflight requests before cross-origin POSTs. Explicitly handle OPTIONS with proper Access-Control-Allow-* headers.
When to Break These Rules
- Use GraphQL when frontend teams have very different data needs and you want to avoid over-fetching or maintaining multiple REST endpoints per client type.
- Use WebSockets for truly real-time bidirectional communication (chat, live collaboration) - REST polling is expensive and lossy at scale.
Reference Files
https://restfulapi.net/https://swagger.io/specification/