REST (Representational State Transfer) is not a protocol or a format — it is an architectural style defined by Roy Fielding in his 2000 dissertation. An interface earns the label “RESTful” only by satisfying a set of constraints. This reference lists all six with Fielding’s definition and the trade-off each imposes.
The six constraints
REST is defined by six constraints, applied on top of a network of components. Five are required; one (code on demand) is optional:
- Client–Server — separate UI from data storage.
- Stateless — each request is self-contained; no server-side session.
- Cacheable — responses declare their cacheability.
- Uniform Interface — URIs, representations, self-descriptive messages, HATEOAS.
- Layered System — components only see the adjacent layer.
- Code on Demand (optional) — server may send executable code to clients.
Each constraint buys a property — scalability, visibility, simplicity — usually at some cost in efficiency or latency.
What each constraint actually means in practice
Client–Server separates concerns: the client handles the user interface and the server handles data storage and business logic. Neither knows about the other’s implementation. This is why a REST API can serve a web app, a mobile app, and a third-party integration from the same endpoints — the clients evolve independently.
Stateless means the server holds no session state between requests. Every request carries all the information needed to process it — authentication token, context, parameters. The benefit is horizontal scalability: any server instance can handle any request with no coordination. The cost is that requests are larger and you cannot rely on server-side state for multi-step workflows.
Cacheable requires responses to identify themselves as cacheable or not. If a response is cacheable, a client or intermediary proxy can reuse it for subsequent equivalent requests. This reduces load and latency significantly for read-heavy APIs. Cache-Control headers are the mechanism; omitting them leaves caching behaviour undefined.
Uniform Interface is the central constraint, with four sub-constraints:
- Resources identified by URIs (
/users/123, not a procedure call) - Manipulation through representations (you send a JSON body, not a direct mutation)
- Self-descriptive messages (the response contains enough information to process it)
- HATEOAS — Hypermedia As The Engine Of Application State (responses contain links to valid next actions)
HATEOAS is the sub-constraint almost every so-called “REST” API skips. A fully RESTful response includes links to related resources and available actions, so a client can navigate the API by following links rather than having the URL structure baked in.
Layered System means a client cannot tell whether it is talking directly to the origin server or to an intermediary (cache, gateway, load balancer). Each component sees only the adjacent layer. This is what makes transparent proxies, CDN edge caches, and API gateways possible without changing client or server code.
Code on Demand (optional) — the server can extend client functionality by transferring executable code such as JavaScript. This is why the web can load scripts that add new capabilities to a page. It is optional because it reduces transparency: the client’s behaviour becomes partially determined by server-sent code, which some security models cannot permit.
The stateless constraint in depth
Stateless is where most scaling benefits live, and it is the most commonly violated constraint in practice. A server-side session looks convenient — you log in once, the session stores your identity, and subsequent requests just reference the session ID. The problem surfaces when you add a second server: the session lives on server A, but the next request might reach server B, which knows nothing about it. Solutions include sticky sessions (which defeat horizontal scaling) or shared session stores (which add latency and a new failure point). The REST solution is to carry the identity in every request — usually as a signed JWT or an OAuth bearer token — and let any server verify it independently.
Notes
- The uniform interface is what most distinguishes REST from RPC; its HATEOAS sub-constraint (hypermedia links driving state) is the part most APIs omit.
- Layered system is what makes transparent caches, gateways and load balancers possible — clients can’t tell whether they’re talking to the origin.
- Satisfying all required constraints yields the scalability and evolvability REST is prized for; violating statelessness or the uniform interface is what quietly turns a “REST” API into something else.
- Many widely used APIs described as “REST” or “RESTful” satisfy only client-server, stateless and cacheable — they use HTTP correctly but skip HATEOAS and the full uniform interface. They are practical and useful; the label is just technically imprecise by Fielding’s definition.