A candidate says a REST API cannot be stateless because it stores orders in a database. Explain why that is wrong by distinguishing the two kinds of state involved.
answer
- Resource state = the data; application state = the conversation
- Client holds where-am-I; server holds what-is-true
- Test: could a cold instance serve this request?
- Turn a wizard into a cart resource
- A database is not a violation
basics
~20 sTwo different things. Resource state is the durable data the API manages - orders, users - and storing it is the point of the API. Application state is per-client context between requests, like where you are in a flow. Statelessness forbids only the second.
solid answer
~50 sStatelessness constrains **application state**, not **resource state**. Resource state is the domain data the API exposes and mutates: orders, users, documents. It is shared, durable, addressable by URL, and identical no matter which client asks. Storing it is the purpose of the API; a REST API with no resource state would have nothing to serve. Application state - also called session or conversational state - is where a particular client is in its interaction: who is logged in, which step of a wizard, which page of a result set, what was selected. REST says this is kept by the client and sent with each request, so the server never needs to remember a client between calls. The practical test is: could a different server instance, with no memory of previous calls, handle this request correctly using only the request plus shared storage? If yes, it is stateless, database or not.
go deeper
Give the two definitions cleanly with one example each, and state that storing orders is resource state and therefore fine.
Add the instance-interchangeability test and the pattern of promoting conversational state into an addressable resource.
Tie it to consequences - cacheability, retry safety, free routing - and name the costs, such as larger requests and repeated per-request auth work.
Frame it as a state-placement decision across client, shared store and node, and discuss which flows genuinely justify server-held context.
## The two words that get conflated Almost every confusion about REST statelessness comes from using "state" for two different things. **Resource state** is the data the API is about. An order, a user profile, a document, an account balance. It is durable, shared across all clients, addressable by a URL such as `/orders/1234`, and changed by requests (`POST`, `PUT`, `PATCH`, `DELETE`). Two different clients asking for `/orders/1234` should see the same thing. Storing it in a database is not a violation of anything - it is the entire job. **Application state** (equivalently session or conversational state) is where one particular client currently is in its interaction with the service. Examples: which user is authenticated on this connection, which step of a five-step signup has been completed, which page of search results is next, which items are selected in the UI, which filter is applied. This state is *about a client*, not about the domain. The REST constraint is: **application state lives on the client**, and each request carries whatever slice of it the server needs. ## Why the distinction is drawn there Application state is what makes servers non-interchangeable. If instance A remembers that this client is on step three, then this client must keep talking to instance A. Resource state does not have that property, because every instance reaches the same database and sees the same order. So the constraint is really about **interchangeability**, and the test is operational: if this exact request arrived at a freshly started instance that had never seen this client, would it be handled correctly? A `GET /orders/1234` with a valid credential: yes - it reads shared storage. A `POST /checkout/next-step` that relies on the server remembering steps one and two: no. ## Concrete pairs - *Stateful*: the server remembers you are on page 3 and `GET /search/next` returns page 4. *Stateless*: the client sends `GET /search?q=shoes&cursor=eyJ...`, which fully describes the position. - *Stateful*: login creates a server-side session object holding your identity and roles; requests carry only its id. *Stateless*: each request carries a self-contained credential the server can validate on its own. - *Stateful*: a checkout flow accumulates in server memory until the final submit. *Stateless*: each step creates or updates a real, addressable resource - `PATCH /carts/abc` - so progress is resource state anyone can read back. That last pattern is the general trick: **turn conversational state into an addressable resource**. A half-finished checkout stops being an in-memory conversation and becomes a cart with an id and a status. It is now durable, inspectable, resumable from another device, and any instance can continue it. ## What follows from getting this right Self-contained requests are cacheable (a proxy can reason about them from the request alone), retryable (a retry means the same thing), debuggable (a captured request reproduces the behaviour in isolation), and routable to any instance. Requests do get larger and authentication work is repeated per call - that is the acknowledged trade. ## Answering the interviewer Say it in one line - statelessness is about session state, not stored data - then give the two definitions, then the instance-interchangeability test. If you want to go further, mention that the durable-data side is exactly why REST APIs can also be cached and load balanced without special routing.
- Where should a multi-step signup flow keep its progress in a stateless API?Make the in-progress signup a real resource: POST /registrations returns an id, then each step patches that resource. Progress becomes resource state in shared storage rather than conversational state in one instance's memory, so any instance can continue it and the user can resume on another device.
- Is caching a response on the server a violation of statelessness?No. A cache is an optimisation over shared or derivable data, and correctness must not depend on it - a cold instance must still answer correctly, just more slowly. It becomes a violation only if the cache holds per-client state that exists nowhere else, so a different instance would answer incorrectly.
A library is stateless toward you: the shelves hold the books (resource state), but the librarian does not remember which page you were on - you carry your own bookmark (application state).
saying these in an interview costs you the question
- Saying a stateless API cannot use a database or must be read-only
- Treating an in-memory HTTP session as acceptable because the session id travels in a cookie
- Confusing statelessness with idempotency or with immutability
- Claiming statelessness means the server keeps nothing at all
- Assuming stateless implies no authentication is possible