Interview Bank · Lesson 1

REST Foundations — interview questions

21 questions · Core / Senior / Staff · pairs with Lesson 1

REST APIRESTful designStatus codesHTTP methodsREST

Published

Use these as active recall, not reading. Read the question, answer it out loud or in writing from memory first, and only then reveal the model answer to grade yourself. Recognizing an answer ≠ being able to produce it under pressure. Filter by difficulty; reveal-all only for a final review pass.

What is REST, precisely?

An architectural style defined by a set of constraints, coined by Roy Fielding — not a protocol, data format, or "JSON over HTTP." An API is "RESTful" only to the degree it honors the constraints. Naming it as a style (not a spec) is the senior tell.

Name the six architectural constraints.

Client–server, stateless, cacheable, uniform interface, layered system, and code-on-demand (the only optional one).

Is REST the same thing as HTTP?

No. REST is a style; HTTP is a protocol that happens to fit it very well. You can apply REST principles over other protocols, and you can absolutely use HTTP un-RESTfully — e.g. tunnelling everything through one POST endpoint (Richardson Level 0).

Resource vs representation — what's the difference?

A resource is the abstract thing identified by a URI (a user, an order). A representation is a snapshot of that resource's state in some format (JSON, XML) transferred over the wire. Clients manipulate representations, never the resource directly — and a resource can have several representations.

What does the statelessness constraint actually require?

Each request must carry everything the server needs to process it; the server keeps no per-client session state between requests. State lives on the client (or in a shared datastore the request points at), not in server memory tied to a connection.

Why does statelessness help you scale?

Because any node can serve any request — no sticky sessions, no session affinity. You scale horizontally by adding boxes behind a load balancer, and a node dying doesn't lose a user's session. It also improves visibility (each request is self-contained, so caches/proxies/monitoring can reason about it alone).

"Stateless" means no database and no cookies, right?

No — a common misconception. It means no server-side session state between requests. Application/resource state in a database is completely fine. Auth state moves into a token sent on every request (e.g. a Bearer/JWT) instead of a server-held session.

What are the costs of statelessness, and how do you mitigate them?

Every request must re-send context (auth, etc.), so requests are larger and you can't lean on cheap in-memory session affinity. You also can't trivially do server-push of session changes. Mitigations: compact signed tokens, caching/CDNs, idempotency keys to make retries safe, and a shared cache/store (Redis) when you genuinely need cross-request state — accepting it's then explicit, not hidden in a node's memory.

How does statelessness shape your authentication design?

It pushes you toward token-based auth: a signed token (JWT) on every request that any node can validate independently, rather than a server-side session looked up from memory. That's why stateless REST and JWT pair so naturally — and why "where does the session live?" is the wrong question for a pure REST API.

What are the four sub-constraints of the uniform interface?

(1) Identification of resources (URIs); (2) manipulation of resources through representations; (3) self-descriptive messages (each message carries enough to be understood — method, media type, status); (4) hypermedia as the engine of application state (HATEOAS).

What is HATEOAS?

Hypermedia As The Engine Of Application State: responses include links advertising the valid next actions, so the client discovers what it can do rather than hard-coding URIs and workflow. The server can then change its URL structure without breaking clients.

If HATEOAS is part of REST, why is it so rare in real APIs?

Because the payoff rarely justifies the cost. Most clients are first-party and version-pinned — they don't dynamically follow links, they're coded against known endpoints. Tooling/codegen and developers expect fixed URLs. So the decoupling HATEOAS buys goes unused, and teams stop at Level 2. The senior move is to know that and say so, not to pretend everyone does L3.

When would you actually invest in HATEOAS / Level 3?

When you have many third-party clients you can't redeploy and need to evolve URLs/workflows without breaking them; when the API models a state machine where the available actions genuinely change (e.g. a payment that can be captured/refunded/voided depending on state — links express the legal transitions); or where discoverability is a product feature.

Describe the Richardson Maturity Model.

A 0–3 ladder of how fully an API uses REST's ideas: L0 one URI / one verb (RPC-over-HTTP, "Swamp of POX"); L1 many resources, each a URI; L2 proper HTTP verbs + status codes; L3 hypermedia (HATEOAS).

What level do most production "REST" APIs sit at?

Level 2 — correct resources, verbs, and status codes, but no hypermedia. That's the pragmatic industry bar.

Is a Level 2 API "really REST" by Fielding's own definition?

Strictly, no — Fielding argues that without the hypermedia constraint it isn't truly REST. But Level 2 is what the industry pragmatically means by "REST." The strong answer names that tension explicitly and then defends the pragmatic choice for the given context, rather than dodging it.

Give a concrete example of a Level 0 system.

Classic SOAP / XML-RPC: a single endpoint (e.g. POST /api) where the action lives in the request body and HTTP is just a transport tunnel. Status and verbs carry no semantic meaning.

REST vs gRPC/RPC — when would you pick each?

REST: resource-oriented, leans on HTTP caching, broad client reach, easy to evolve, great for public/edge-facing APIs. gRPC/RPC: low-latency internal service-to-service, strict typed contracts (protobuf), bidirectional streaming, high throughput — but binary, less browser/edge-friendly, weaker HTTP-cache story. Rule of thumb: REST at the edge, gRPC between internal services.

REST vs GraphQL — what are the trade-offs?

GraphQL: client shapes the query, killing over-/under-fetching; one endpoint; excellent for many varied clients. Costs: HTTP caching is hard (usually POST), query-cost/N+1 control, and you lose HTTP-native semantics (status, methods, conditional requests). REST: simpler, cache-friendly, ubiquitous, but fixed response shapes lead to over-/under-fetching. Many systems run both.

A team says "let's make our API RESTful." How do you advise them?

First ask why — what outcome do they want (evolvability, caching, DX, broad reach)? Then assess current maturity. For most, the goal is a clean Level 2: good resource modeling, correct verbs/status codes, real cache headers, consistent errors. Pursue L3/HATEOAS only if uncontrollable third-party clients or a genuine state machine demand it. Don't chase REST purity for its own sake — tie every constraint back to a concrete benefit.

Why do interviewers open with "what makes an API RESTful?"

Because the answer reveals whether you understand the why behind design — the constraints and their trade-offs — versus just the surface mechanics (verbs, JSON). It's a fast, reliable predictor of the quality of every downstream design answer you'll give.

REST design-round framework — drive any "design a REST API" prompt through these, out loud:
  1. Model resources & URIs — nouns not verbs, collections vs items (/orders, /orders/{id}), nesting only for true ownership.
  2. Map methods & status codes — GET/POST/PUT/PATCH/DELETE to the right semantics; 2xx/4xx/5xx that mean what they say.
  3. Idempotency & caching — safe/idempotent verbs, idempotency keys for POST, ETag/Cache-Control/conditional requests.
  4. Pagination, filtering & sorting — cursor vs offset, bounded page sizes, consistent query params.
  5. AuthN/AuthZ — bearer tokens on every request (stateless), scopes/roles, transport security, rate limits (OWASP API Top 10).
  6. Versioning & evolution — additive changes, deprecation policy, URL vs header versioning.
  7. Errors & contracts — a consistent error envelope (e.g. RFC 9457 problem+json), correlation IDs, documented schema.
Design a RESTful API for a blogging platform (posts, comments, authors). Walk the resource model and maturity level.

A strong answer covers: resources as nouns — /posts, /posts/{id}, /posts/{id}/comments, /authors/{id} — with nesting only where ownership is real and a flat /comments/{id} for direct access → verbs mapped cleanly (GET list/read, POST create, PATCH partial edit, DELETE) with correct status codes (201 + Location on create, 404 vs 410, 409 on conflict) → statelessness: bearer token on every request, authorization checks per resource (an author edits only their own posts) → caching with ETag/Last-Modified on reads and conditional requests on writes → pagination + filtering on the collections (cursor-based, bounded page size) → a consistent error envelope and a versioning/deprecation story → name the maturity call: deliberately Level 2 (verbs + status codes, no HATEOAS) because clients are first-party, and say when you'd move to L3.

An interviewer hands you a Level 0 "JSON over HTTP" API (one POST /api with an action field) and asks you to make it RESTful. How do you approach it?

A strong answer covers: first diagnose — it's RPC tunnelled through one endpoint, so HTTP verbs, status codes, and caching all carry zero meaning → climb the Richardson ladder incrementally rather than big-bang: L1 split the single endpoint into resource URIs, L2 map each action onto the correct method + status code and expose real cache headers → preserve the old endpoint behind a versioned facade so existing clients don't break; run both during migration → tie every change to a benefit (cacheability, idempotent retries, intermediary visibility) instead of chasing purity → stop at L2 unless uncontrollable third-party clients or a genuine state machine justify HATEOAS → call out migration risks: dual-write/dual-read consistency, client cutover, and a deprecation timeline with metrics on old-endpoint traffic.