REST API Design

REST (Representational State Transfer) is an architectural style for building APIs around resources and standard HTTP semantics. A good REST API is predictable, observable, secure, and evolvable — clients can guess how it behaves because it follows conventions.

Most REST design comes down to two habits: model your domain as resources, and use HTTP the way it was meant to be used. The rest is consistency.

TL;DR

Quick Example

A create endpoint that uses the right method, status, and Location header, with a consistent response envelope:

Resource Modeling

Use plural nouns for collections and avoid verbs in paths:

Use stable, public identifiers in URLs (/projects/proj_abc123) and avoid leaking internal database IDs.

HTTP Methods

GET must never change state. PUT replaces; PATCH applies a partial update (JSON Merge Patch or JSON Patch).

Status Codes

A practical working set:

Error Handling

Pick one error shape and use it everywhere so clients can handle failures reliably:

Keep code stable even if message changes, include a request_id, and never leak stack traces or secrets.

Pagination, Filtering, Sorting

Return pagination metadata (next_cursor, has_more), keep filters explicit (?status=active), and document allowed sort keys (?sort=-created_at).

Idempotency for Writes

For "create payment" or "create order," clients may retry. Accept an Idempotency-Key header and store the result keyed by (user, key) for a window, so retries don't create duplicates.

Versioning

Prefer evolvable changes (additive fields, new endpoints) that need no version bump. When you must version, URL versioning (/v1/projects) is the simplest and most explicit. See API Versioning.

Best Practices

Common Mistakes

Returning 200 for everything

Clients can't reason about failures if every response is 200.

Verbs in resource paths

FAQ

PUT or PATCH?

PUT replaces the entire resource (and is idempotent). PATCH applies a partial update — send only the fields that change. Use PATCH for typical "edit a couple of fields" operations.

When should I version my API?

Only when you make a breaking change you can't avoid. Additive changes (new optional fields, new endpoints) don't need a version bump. When you do version, be consistent — URL versioning is simplest.

Offset or cursor pagination?

Offset is fine for small, stable, admin-style lists. Use cursor pagination for feeds and large datasets where rows are inserted/deleted, since offsets drift and get slow.

401 or 403?

401 Unauthorized means "not authenticated" (no/invalid credentials). 403 Forbidden means "authenticated, but not allowed." Use 404 instead of 403 when you don't want to reveal that a resource exists.

Related Topics

References