Day 13 · Week 2 · Web + Data

REST architecture.

Most APIs that call themselves RESTful aren't. The term has been diluted into 'JSON over HTTP.' Today we restore the precise meaning, and — more importantly — separate the rules worth following from the academic ones nobody actually does.

~22 min readFielding demystifieddesign rules
REST is the only "architectural style" most backend devs are ever asked about in interviews. Knowing the real definition — and the real practice — separates juniors from people who can lead an API design discussion.

Where REST came from

In 2000, a researcher named Roy Fielding wrote a doctoral dissertation that retroactively described the architecture of the web — why HTTP scaled when other protocols didn't. He gave it a name: REST (Representational State Transfer).

So REST is not a protocol. It's not a format. It's a set of architectural constraints. If your API satisfies them, it's RESTful. If not, it's just an API. (Both are fine — but pretending matters.)

The six constraints

ConstraintWhat it means
1. Client-ServerSeparate concerns: client handles UI, server handles data. They evolve independently.
2. StatelessEach request contains everything needed to process it. The server doesn't remember the client.
3. CacheableResponses must declare whether they can be cached and for how long.
4. Layered systemThe client doesn't know if it's talking to the actual server or a load balancer / proxy / CDN.
5. Uniform interfaceOne consistent way to identify, read, and modify resources (URIs + standard methods).
6. Code on demand (optional)Server can ship JavaScript to extend the client. Rarely listed as defining REST.

The first five matter. The sixth is a footnote — Fielding even marked it optional.

The mental model · resources

The single most useful insight from REST: your API is a collection of resources, not a collection of actions.

❌ RPC-style — verbs in URLs

  • POST /getUser
  • POST /createUser
  • POST /updateUserEmail
  • POST /deleteUser
  • POST /listUsers

You'll explode in endpoint count. Each new operation is a new URL.

✅ REST — resources + standard methods

  • GET /users — list
  • POST /users — create
  • GET /users/42 — fetch one
  • PUT /users/42 — replace
  • PATCH /users/42 — partial update
  • DELETE /users/42 — remove

Five operations, one URL pattern. Predictable.

🔑 The naming rule

URIs are nouns. The HTTP method is the verb. GET /users is correct. GET /getUsers is REST cosplay. Always plural for collections (/users), singular sub-resources via id (/users/42/orders).

Nesting resources

Sub-resources express ownership:

GET    /users/42/orders          # orders for user 42
POST   /users/42/orders          # create an order for user 42
GET    /users/42/orders/9        # specific order
DELETE /users/42/orders/9        # remove it

Two informal rules in practice:

Statelessness — the constraint that scales

"Each request contains everything to process it" sounds abstract. Concretely:

❌ Stateful

POST /login
→ server stores session
→ returns session-id

GET /me
→ server looks up session
→ from in-memory map

Server holds state. Hard to scale to many machines.

✅ Stateless

POST /login
→ returns signed JWT

GET /me
Authorization: Bearer eyJ...
→ verify token signature
→ all info in the token

Any server can handle any request. Trivial to scale.

🧠 Why this constraint matters in production

Statelessness lets you put a load balancer in front of N replicas of your service. No sticky sessions, no shared session store. Add machines for traffic spikes; remove them when quiet. This is why JWT-based auth dominates modern REST APIs.

Cacheable — leverage the network

HTTP caching is built into the protocol. Use it:

GET /products/42 HTTP/1.1\n\nHTTP/1.1 200 OK\nCache-Control: public, max-age=3600\nETag: "abc123"

The Cache-Control: max-age=3600 tells browsers, CDNs, proxies — "you can cache this for an hour." A subsequent request can be answered from cache without ever hitting your server.

ETag + If-None-Match lets clients ask "is the version I have still valid?" — server responds 304 Not Modified with no body if yes.

The Richardson Maturity Model

Leonard Richardson described how "RESTful" a given API is on a four-step ladder. Most "REST" APIs are at level 2 — that's fine.

Level 0 · POXsingle URL, single verb (POST), all RPCLevel 1 · Resourcesmultiple URLs, but still POST-onlyLevel 2 · HTTP verbsGET, POST, PUT, DELETE used semantically · ← most APIs hereLevel 3 · Hypermediaresponses include links to related actions (HATEOAS)
The four levels of REST maturity. Most production APIs live at level 2.

HATEOAS — the academic constraint nobody follows

Level 3 says responses should include links the client can follow:

{
  "id": 42,
  "status": "paid",
  "_links": {
    "self":    { "href": "/orders/42" },
    "refund":  { "href": "/orders/42/refund" },
    "invoice": { "href": "/orders/42/invoice" }
  }
}

Idea: clients discover capabilities at runtime, not by reading docs. In practice, almost no public API does this. Clients are written against API docs, not by exploring links. Spring HATEOAS exists; it's mostly used in enterprise systems with strict requirements. Don't worry about HATEOAS for interviews — recognize the term, move on.

How Spring expresses REST

@RestController
@RequestMapping("/users")
public class UserController {

  private final UserService userService;

  @GetMapping
  public List<UserDto> list() { return userService.findAll(); }

  @GetMapping("/{id}")
  public UserDto get(@PathVariable Long id) { return userService.findById(id); }

  @PostMapping
  @ResponseStatus(HttpStatus.CREATED)
  public UserDto create(@Valid @RequestBody CreateUserRequest req) { return userService.create(req); }

  @PatchMapping("/{id}")
  public UserDto update(@PathVariable Long id, @RequestBody PatchUserRequest req) { return userService.patch(id, req); }

  @DeleteMapping("/{id}")
  @ResponseStatus(HttpStatus.NO_CONTENT)
  public void delete(@PathVariable Long id) { userService.delete(id); }
}

Every line maps cleanly to REST conventions: @GetMapping, plural collection in path, @PathVariable for the resource id, 201 Created on POST, 204 No Content on DELETE. Spring makes the right thing easy.

The five most common REST mistakes

MistakeRight way
GET /getAllUsersGET /users
POST /users/42/deleteDELETE /users/42
Returning 200 OK with { "error": ... }Return 4xx / 5xx with error body
Same URL for HTML and JSON via ?format=jsonContent negotiation via Accept header
Nesting beyond 2 levels (/a/1/b/2/c/3)Promote inner resources to top level

API versioning — the unavoidable conversation

You'll change your API. Clients depend on it. How do you make changes without breaking them?

URL-based · most common

  • /v1/users · /v2/users
  • Easy to route, easy to test
  • "Clutters" URLs but everyone accepts it
  • Stripe, Twilio, GitHub use this

Header-based · cleaner but fragile

  • Accept: application/vnd.api.v2+json
  • URLs stay clean
  • Hard to test in browsers / curl
  • Caching gets weird
  • Few public APIs use this in practice
📌 Practical advice

Use URL versioning for public APIs. Treat each version as a contract — once published, never break it. New version when you must break. Within a version, make additive changes (new optional fields are safe; renaming fields is not).

REST vs. GraphQL vs. gRPC — the lay of the land

StyleBest forTradeoff
RESTPublic APIs, broad client compatibilityMultiple round-trips for related data
GraphQLComplex frontends fetching many related objectsServer complexity; harder to cache
gRPCInternal microservice ↔ microservice callsBinary; harder to debug; not browser-native

For your career trajectory: master REST. It's the lingua franca. The other two come up only when a specific need arises.

Pause & reflect

Lock in today's learning

Take your time. These come up in real design discussions.

  1. What is REST in one sentence? (Hint: not a protocol)
  2. Name three of Fielding's six constraints and why they matter.
  3. What's the resource-based naming rule? Give a wrong example and a right one.
  4. Why does statelessness make scaling easier?
  5. What is the Richardson Maturity Model and where do most production APIs live?
  6. Name three common REST mistakes you'll watch for in code review.

End of Day 13. Tomorrow: JSP — a brief historical tour, the bridge to today's frontend separation.