REST HTTP Fundamentals
This page is intentionally about the contract surface of HTTP APIs: URLs, methods, status codes, error shapes, validation, and idempotency.
For operational guidance (security, observability, performance, retries, rollout checks), use API best practices. For full JSON examples per verb, use Payloads and responses.
Request Path Through The Stack
Section titled “Request Path Through The Stack”A single HTTP call moves through several layers. Names vary by framework, but the idea is stable:
- Client builds a request (method, path, headers, optional body).
- DNS and TLS resolve the host and encrypt bytes on the wire.
- Gateway / ingress may terminate TLS, enforce auth, rate limits, or routing rules.
- Router matches path + method to a handler (controller).
- Validation checks shape and types (DTO / schema) at the boundary — never trust raw client input deeper in the stack.
- Domain / service applies business rules and talks to repositories or other services.
- Persistence stores durable state; the response travels back with status, headers, and optional JSON body.
See HTTP for operators for transport-level detail (keep-alive, redirects, common headers).
flowchart TD client[Client] dnsTls["DNS and TLS"] gateway["Gateway / ingress"] router[Router] handler[Handler] validate["Validate DTO"] domain["Domain / service"] store[Persistence] client --> dnsTls --> gateway --> router --> handler --> validate --> domain --> store
Minimal Example First
Section titled “Minimal Example First”Below is a smallest useful exchange: a client asks for one resource; the server answers with 200 and a small JSON object. Real APIs often wrap payloads in a data envelope — that pattern is documented on the payloads page.
GET /v1/users/01933f8a-7d4e-7c9a-b4e1-1c2d3e4f5a6b HTTP/1.1Host: api.example.comAccept: application/jsonHTTP/1.1 200 OKContent-Type: application/json
Try this request
Section titled “Try this request”api.example.com is only a placeholder; substitute your API base URL. From a terminal, curl is enough to reproduce the GET and see status plus headers (-i):
curl -i --get \ "https://api.example.com/v1/users/01933f8a-7d4e-7c9a-b4e1-1c2d3e4f5a6b" \ -H "Accept: application/json"HTTPie is another open-source CLI option with readable output. For a GUI, open-source clients such as Insomnia or Bruno work well for the same method, URL, and headers.
JSON request bodies should use Content-Type: application/json. If the client sends the wrong or missing type for a JSON body, servers often respond with 415 Unsupported Media Type.
Resource Modeling and URLs
Section titled “Resource Modeling and URLs”- Nouns, not verbs — Prefer
/users/123/ordersover/getUserOrders. - Plural collections —
/users,/orders. - Shallow nesting — Keep hierarchy to one or two levels; deep trees become brittle and hard to cache.
- Lowercase, hyphenated paths —
kebab-casein URLs; reservesnake_casefor JSON fields if that is your JSON convention. - Version in the path — For example
/v1/...; simple and explicit for many teams.
HTTP Method Semantics
Section titled “HTTP Method Semantics”- GET — Safe and idempotent; no body; reads state.
- POST — Create or non-idempotent actions; not assumed safe to repeat without an Idempotency-Key.
- PUT — Full replace; idempotent with stable client-provided identity when used that way.
- PATCH — Partial update; document merge vs JSON Patch semantics.
- DELETE — Idempotent at the HTTP level (repeat delete remains non-harmful).
On 201 Created, return a Location header for the new resource and usually return the created representation so clients can skip a follow-up GET.
Status Codes and Error Contract
Section titled “Status Codes and Error Contract”Both layers matter:
- HTTP status tells generic clients and intermediaries what happened (
404,422,429,5xx). Proxies, caches, and retries key off this code. - JSON error envelope (for example
{ "error": { "code", "message", "details", "trace_id" } }) gives humans and app-specific clients structured detail.
A validation failure is still 422 even when the body includes field-level errors. A rate limit is still 429 even when the JSON explains limits. Map domain failures to HTTP once (middleware or central render layer), not ad hoc per handler.
Use a consistent common set:
- 2xx —
200OK,201created,204no content (common for DELETE). - 4xx —
400bad input,401not authenticated,403not authorized,404missing,409conflict,412precondition failed (ETag),422validation,429rate limited. - 5xx — server or dependency failure; clients may retry only when the operation is idempotent or keyed.
Include a correlation or trace ID on every response (header and/or inside the error envelope) and propagate it through logs and downstream calls.
Contracts and Validation
Section titled “Contracts and Validation”- Treat OpenAPI (Swagger) as the contract — generate docs, mocks, and clients where practical.
- Python: FastAPI + Pydantic gives validation, serialization, and OpenAPI from types (layout reference).
- Go: chi or Gin with
validatortags, or spec-first flow with oapi-codegen (layout reference). - Validate at the boundary — parse and reject bad input before domain logic runs.
Concurrency and Idempotency
Section titled “Concurrency and Idempotency”- ETag +
If-Matchon PUT/PATCH for optimistic concurrency; respond412when the precondition fails. Idempotency-Keyheader on POSTs that create side effects or charge money — store(key, principal) → responsefor a bounded TTL (for example 24h) so retries are safe behind load balancers.
API Contract Review Checklist
Section titled “API Contract Review Checklist”- Resource naming is noun-based, stable, and versioned.
- Method semantics match behavior (
GETsafe,PUT/DELETEidempotent by contract). - Status code mapping is consistent across endpoints.
- Error envelope shape is stable and documented.
- Input validation happens at boundary parsing.
- Idempotency or precondition strategy is explicit for writes.
- Trace or correlation ID is included in responses.
Further Reading
Section titled “Further Reading”- Operational guardrails across security, observability, reliability, performance, and rollout checks: API best practices.
- Full request and response examples per endpoint shape: Payloads and responses.
- Language implementation layouts: Python (FastAPI) and Go (chi).
- Transport-level behavior and headers: HTTP for operators.