Quick reference for REST semantics, status codes, versioning, pagination, error formats, and protocol trade-offs.
RESTgRPCVersioningPagination
REST Basics
- Plural nouns, lowercase, hyphenated:
/users/42/orders.
- No verbs in path — the HTTP method is the verb.
- Richardson: L2 (verbs + codes) is the practical target; L3 = HATEOAS.
- Never return 200 with an error body.
Methods
| Verb | Idempotent | Use |
| GET | yes | Read |
| POST | no | Create |
| PUT | yes | Replace |
| PATCH | maybe | Partial |
| DELETE | yes | Remove |
Status Codes
| 200 / 201 / 204 | OK / Created / No Content |
| 304 | Not Modified (cache) |
| 400 / 401 / 403 / 404 | Bad / Unauth / Forbidden / Missing |
| 409 / 422 / 429 | Conflict / Unprocessable / Rate limited |
| 500 / 503 | Server error / Unavailable |
4xx = client, don't retry. 5xx = server, retry w/ backoff.
Versioning & Paging
| Version | Where |
| URI | /v2/users (default) |
| Header | API-Version: 2 |
| Media | vnd.api.v2+json |
Bump only on breaking changes. Prefer cursor over offset pagination for scale.
Reliability Headers
Idempotency-Key — safe POST retries.
Retry-After + RateLimit-* on 429.
ETag + If-None-Match → 304.
If-Match → optimistic concurrency.
Cache-Control freshness.
Errors — RFC 9457
Content-Type: application/problem+json
{
"type": "/errors/validation",
"title": "Validation failed",
"status": 422,
"detail": "email invalid",
"instance": "/users"
}
Auth
- API key — server-to-server identity.
- OAuth 2.0 — delegated third-party, scopes.
- JWT bearer — stateless, short-lived + refresh.
- Always TLS; never secrets in query string.
REST vs GraphQL vs gRPC
| Pick | When |
| REST | Public APIs, CRUD, HTTP caching |
| GraphQL | Rich clients, avoid over-fetch |
| gRPC | Internal, low-latency, streaming |
Webhooks: signed (HMAC), event ID for dedup, retry w/ backoff.