skip to content

How does REST, as an architectural style layered on HTTP, encode client-server request-response mechanics plus its statelessness constraint, and what does that constraint forbid a server from doing between requests?

level: seniorimportance: should knowfreq 65%

answer

  1. HTTP = transport, REST = constraints on top
  2. client sends method+URL+headers+body
  3. REST statelessness = full context per request
  4. uniform interface: GET/POST/PUT/DELETE semantics
  5. no session held server-side between calls

basics

~20 s

HTTP is built as a request-response protocol: a browser or app (client) sends an HTTP request to a URL, and a web server responds with data or a status. REST is a set of design rules on top of HTTP saying, among other things, each request must be self-contained (stateless) and resources should be handled through a uniform set of methods like GET/POST/PUT/DELETE.

solid answer

~50 s

HTTP is a textbook client-server protocol: the client opens a connection and sends a request with a method, a URL identifying a resource, headers, and optionally a body; the server processes it and returns a status code plus a response body, and for stateless HTTP the logical transaction is then over. REST layers architectural constraints on top of that transport: resources are identified by URLs, manipulated through a uniform interface (GET/POST/PUT/PATCH/DELETE with well-defined semantics), representations are self-descriptive, and — critically — the interaction must be stateless: no client context is stored on the server between requests, so each request must carry everything needed to be understood on its own. That statelessness constraint is what lets REST APIs be freely load-balanced and cached, at the cost of larger/more repetitive per-request payloads and no server-held 'conversation' the client can rely on across calls.

go deeper

for a junior

Should know that a browser sends an HTTP request to a URL and gets a response back, and identify which side is the client.

for a middle

Should distinguish HTTP (protocol) from REST (a style of using it) and name the common HTTP methods with rough semantics.

for a senior

Should explain REST's statelessness constraint concretely (token-per-request) and connect it to load balancing/caching benefits.

for a principal

Should diagnose subtle statelessness violations (e.g., IP-keyed server-side session) and reason about the trade-offs of relocating state versus faking statelessness.

## Two layers, routinely conflated HTTP and REST are two different things that are often conflated: HTTP is the transport protocol, and REST (Representational State Transfer) is an architectural style — a set of constraints — that HTTP happens to satisfy well when used a certain way, which is why "REST API" almost always means "an HTTP API designed according to REST's constraints." Understanding how they instantiate the client-server style means looking at both layers. ## The HTTP layer At the HTTP layer, the client-server shape is explicit in the protocol design: - A client (a browser, a mobile app, curl, another backend service acting as a client) opens a TCP connection and sends a request line — a method (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`), a path identifying a resource, headers, and optionally a body. - The server, listening on a port, receives that request, does whatever work it implies, and sends back a status line plus headers and a body. - The server never initiates an HTTP request to a client on its own; the client always goes first, which is the base client-server asymmetry. ## What REST layers on top REST adds architectural constraints on top of raw HTTP's request-response mechanics, and the one most relevant here is **statelessness**: REST requires that each request from client to server contain all the information the server needs to understand and process it, with no reliance on server-held context from a previous request. Concretely, a RESTful API doesn't say "remember, I logged in three requests ago, so trust this one" — it requires the client to send an auth token on every single call, and the server validates that token fresh every time rather than consulting an in-memory "is this connection authenticated" flag. REST also mandates a **uniform interface**: resources are manipulated through a small, fixed set of verbs with agreed semantics, and responses are self-descriptive via content-type headers. | Method | Its agreed semantics | |---|---| | `GET` | is safe/idempotent and doesn't change state | | `PUT` | replaces a resource idempotently | | `POST` | creates or triggers a non-idempotent action | | `DELETE` | removes a resource | ## Why the constraint is hard rather than optional The reason REST bakes statelessness in as a hard constraint, rather than leaving it optional, is precisely the scalability argument central to this leaf: an HTTP server that holds no per-client session state can be freely replicated behind a load balancer, because literally any instance can service literally any request — there's no need for sticky routing, and a crashed instance loses nothing session-related. It also makes intermediate components — caches, proxies, CDNs — able to reason about and cache a response purely from the request that produced it, without needing to track a session. ## The trade-off The trade-off, as with stateless servers generally, is that every request now carries more: authentication has to be re-verified on every call, and any multi-step process that would naturally be "stateful" in a raw protocol has to be re-modeled as a series of self-contained requests against a persisted resource — e.g., a shopping cart is a resource with an ID that the client fetches and updates by ID on each call, rather than an in-memory server-side object tied to a live connection. ## Failure modes Failure modes here are distinctive to REST-over-HTTP: - **Incorrect use of HTTP methods** (a `GET` that has side effects, breaking caching and idempotency assumptions — browsers and proxies may retry or prefetch GETs assuming they're safe) causes subtle bugs. - **Treating an inherently stateful workflow as if REST's statelessness didn't apply** (storing an in-memory "current step" on the server keyed by IP or an implicit session) breaks the moment the request lands on a different server instance behind a load balancer, producing intermittent "my progress vanished" bugs hard to reproduce on a single-instance dev setup. ## Where you have already seen it A concrete, well-known real-world instance: the GitHub REST API requires a token in the `Authorization` header on every call — there is no notion of "you already authenticated a minute ago" — which is precisely what lets GitHub route any given API call to any of its many backend instances without needing session affinity.

  • Can an HTTP-based API be non-RESTful while still being client-server?
    Yes — client-server is the broader structural style, and REST is one particular set of constraints layered on top of HTTP. An API that keeps server-side session state tied to a cookie, or uses only POST for everything regardless of semantics, is still client-server (client initiates, server responds) but violates REST's statelessness and uniform-interface constraints.
  • Why does putting a caching proxy in front of a REST API work so well specifically because of statelessness?
    Because a stateless response depends only on the request that produced it (method, URL, headers), a cache can safely store and replay that response for an identical future request without needing to know anything about a client's session or prior interactions — a stateful response could differ per session even for an identical URL, making it unsafe to cache generically.
  • A team implements 'statelessness' by storing the session in a server-side in-memory map keyed by the client's IP address instead of requiring a token per request. Why does this still violate REST's statelessness constraint?
    The server is still holding context between requests and relying on it implicitly — the request itself doesn't carry everything needed to process it, so any different server instance, or the same client from a different IP, breaks the interaction. True statelessness means the request is self-describing, not that the mechanism used to fake statefulness is invisible.

It's like paying with a fresh, self-contained cheque every time instead of running a bar tab: the vendor (server) doesn't need to remember who you are from your last purchase because each cheque (request) carries all the proof and details needed on its own.

saying these in an interview costs you the question

  • Treats HTTP and REST as synonyms
  • Thinks 'stateless' means the server can't use cookies or tokens at all
  • Believes REST requires JSON specifically
  • Can't explain why GET should be idempotent/side-effect-free
  • Doesn't know statelessness is what enables simple load balancing/caching for REST APIs

context