REST APIs In Depth

API Types & Design — REST APIs In Depth
API Types & Design
Chapter 3 · REST APIs In Depth

🏛️ REST APIs In Depth

Chapter 2 covered HTTP's raw building blocks — methods, status codes, headers. REST is what turns those building blocks into a coherent architectural style. It comes from Roy Fielding's year-2000 doctoral dissertation, and it's a set of constraints, not a format you can validate a request against — which is both REST's greatest flexibility and, as this chapter is honest about, its biggest practical weak spot.

What REST Actually Stands For

REST stands for REpresentational State Transfer. Unpacked: a client interacts with a representation of some piece of server-side state (a JSON object representing a user, say), and every request/response transfers that representation back and forth. Unlike SOAP (Chapter 5), which has a formal contract language (WSDL) a request can be validated against, there is no "REST specification" — just a style. That means two APIs can both honestly call themselves "RESTful" while looking fairly different from each other.

Resources: Nouns, Not Verbs

The core idea: REST organizes an API around resources — nouns, like users, orders, or products — rather than baking actions into the URL itself. The HTTP method (from Chapter 2) supplies the verb; the URL supplies the noun.

RPC-Style Naming vs. REST Resource Naming

Verb-in-the-URL (not REST)

POST /getUserData?id=42
POST /createOrder
POST /deleteComment?id=9

Resource + Method (REST)

GET /users/42
POST /orders
DELETE /comments/9

Notice the RPC-style column crams the verb into the path itself (getUserData, createOrder) and defaults everything to POST. The REST column lets the URL identify what and the HTTP method say what to do with it — which is exactly why Chapter 2's method table matters so much here.

The Architectural Constraints

Fielding's dissertation defines REST through a handful of constraints an API should follow. Client-server separation was already covered in Chapter 1 — here are the rest:

ConstraintWhat It MeansPractical Example
StatelessnessEach request carries everything needed to understand it; the server keeps no memory of prior requestsEvery request includes its own auth token, not a server-side session lookup
CacheabilityResponses must say whether they can be cachedCache-Control headers marking a response as cacheable or not
Uniform InterfaceResources identified by URL, manipulated via representations, self-descriptive messages, hypermedia-driven (HATEOAS)A consistent /resource/id shape across the whole API
Layered SystemThe client can't necessarily tell if it's talking to the origin server directly or through intermediariesA load balancer or caching proxy sitting transparently in front of the real server
Code-on-Demand (optional)The server can optionally send executable logic to the clientRarely used in modern REST APIs — mentioned for completeness

Statelessness in Practice

This is the constraint with the biggest everyday impact. An older, stateful web app might log a user in once and store their identity server-side in a session, referenced by a cookie on every later request. A stateless REST API instead expects every single request to prove who's asking, independently:

Two Stateless Requests — Each Self-Contained

// Request 1 GET /orders/101 HTTP/1.1 Authorization: Bearer abc123 // Request 2 — no memory of Request 1, so the token is sent again GET /orders/102 HTTP/1.1 Authorization: Bearer abc123

The payoff: any server behind a load balancer can handle any request, since none of them depend on a specific server "remembering" a client from before — which is exactly why statelessness makes REST APIs so much easier to scale horizontally.

HATEOAS: The Constraint Everyone Skips

HATEOAS (Hypermedia As The Engine Of Application State) says a response shouldn't just return raw data — it should include links describing what the client can do next, so the client doesn't need to hard-code every related URL in advance.

Plain JSON vs. Hypermedia-Driven JSON

Without HATEOAS

{ "id": 101, "status": "pending" }
The client has to already know the URL for cancelling this order.

With HATEOAS

{ "id": 101, "status": "pending", "links": { "self": "/orders/101", "cancel": "/orders/101/cancel" } }
The response itself tells the client what's possible next.

Here's the honest part: most real-world "RESTful" APIs skip HATEOAS almost entirely — clients are usually hard-coded against documented URLs rather than following links dynamically. Strictly speaking, an API missing HATEOAS isn't fully REST by Fielding's own definition; in practice, the industry mostly calls "HTTP + JSON, organized around resources" REST anyway, HATEOAS or not.

Why REST Became the Default

Riding on plain HTTP means every browser, script, and tool already speaks it natively — no special client library required. Statelessness makes horizontal scaling straightforward. JSON is human-readable and easy to debug. And HTTP's own caching mechanisms can be reused rather than reinvented. Chapter 4 turns these architectural ideas into the concrete design patterns real REST APIs use day to day — versioning, pagination, and more.

💻 Coding Challenges

Challenge 1: Nouns Not Verbs

Rewrite each of these as a proper REST resource + HTTP method pair: GET /getUser?id=5, POST /createOrder, POST /deleteComment?id=9.

Goal: Practice separating the "noun" (the URL) from the "verb" (the HTTP method).

→ Solution

Challenge 2: Identify a Statelessness Violation

A server stores "the user's last search query" in a server-side session, and a later request just says GET /search/repeat expecting the server to remember it. Explain why this violates REST's statelessness constraint, and how you'd redesign the request to fix it.

Goal: Practice recognizing a stateful design masquerading as REST.

→ Solution

Challenge 3: Add HATEOAS Links

Given { "id": 55, "status": "shipped" } for an order resource, add a plausible links object with at least two hypermedia links a client might need next.

Goal: Practice designing a response that describes its own next steps.

→ Solution

⚠️ Gotcha: Calling Anything With JSON Over HTTP "RESTful"

It's extremely common to hear "REST API" used to mean nothing more than "an HTTP API that returns JSON" — with no statelessness guarantee, no resource-based URL design, and no hypermedia at all. That's not necessarily wrong in casual usage, but it's worth knowing the difference: an API that stores session state server-side, uses verb-heavy URLs like /processOrder, and never includes hypermedia links is, strictly speaking, an HTTP API following some REST-ish conventions — not a fully Fielding-compliant REST API. Knowing which constraints an API actually honors (and which it's skipped) matters more than whether it wears the "REST" label.

🎯 What's Next

The next chapter, REST API Design Practices, gets practical: versioning strategies, pagination, filtering and sorting query parameters, idempotency in real designs, and rate limiting — the day-to-day patterns that turn this chapter's architectural ideas into a real, usable API.