flowchart LR
Req(["Req"]) --> sel
St(["State"]) --> sel
sel[["select"]] --> Data(["Data"])
Data --> arr[["arrange"]] --> Tree(["Tree"]) --> pres[["present"]] --> Doc(["Doc"])
Chapter 4. The Factorization
REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.
— Roy T. Fielding, dissertation §5.1.5, 2000
Chapter 3 stripped two pages by hand and called the result illustration; this chapter proves the universal claim. The strips become the factors of a typed pipeline. A definition — properness — separates real factorizations from trivial ones. And the analysis theorem guarantees that every read factors — and that the factorization can be made proper. The chapter closes with the method’s debt to Roy Fielding — author of the REST dissertation — and with the four timelines a proper factorization gives the document.
The pipeline
Chapter 3’s strips, read as function types:
select : Req × State → Data which facts
arrange : Data → Tree what structure
present : Tree → Doc what appearance
read = present ∘ arrange ∘ select (4.1)
select, arrange, and present are Chapter 3’s Selection, Arrangement, and Style; Tree is the arranged data — what Chapter 3 called Content, before style touches it.
The pipeline of (4.1). Rectangles are the factors; rounded nodes are values. Under S4 — the fourth properness condition defined below — each factor’s output is a web resource: it has a URI, and a GET on that URI returns it.
Prop. 4.2 (Existence, trivial). Every read factors as (4.1). Proof: let select and present be identities up to retyping and stuff the entire application into arrange — call this the fused factorization. ∎
Proposition 4.2 matters for what its proof shows: a factorization always exists, so the bare existence of one carries no information. The information is in whether the factors are genuinely separate. Definition 4.3 states that separation as four checkable properties — what “declarative architecture” means, once it is required to mean anything checkable. It is the book’s central definition.
Properness
Definition 4.3. A factorization (select, arrange, present) is proper iff:
S1 — Obliviousness. Each factor communicates with the next only through its output. arrange sees data, never the request. present sees a tree, never the data. No side channels: arrange and present are constant in Req and State except through their arguments.
S2 — Declarativity. Each factor is the meaning of a term in a language — there exist three languages, one per factor, with independently defined semantics such that select = ⟦q⟧, arrange = ⟦t⟧, present = ⟦s⟧ for terms q, t, s. This is what “declarative” means, made precise: the meaning of the query does not depend on the stylesheet, because each language’s semantics is closed.
S3 — Substitutability. Replace any factor with another term of its language and you still have a web application; the change is confined to that factor’s concern.
S4 — Addressability. Each factor’s output is itself a web resource: the data produced by select has a URI and is dereferenceable, independently of the document it is destined to become.
S1–S3 could describe any well-factored program. S4 is the web condition: the factorization itself goes public, exposed through the web’s own reference mechanism. An application satisfying S1–S4 is part of the web at every layer, not only at its rendered surface.
The dashboard makes it concrete: select pulls the panel’s title and value, arrange nests them into a card, present themes the card. S4 is the property you can check by hand. Each factor’s output — the data, the card, the themed page — has its own URL and dereferences: a GET on the URL returns it.
Three of these properties were written down by the web’s own architects — as advice. Architecture of the World Wide Web, Volume One (W3C Recommendation, 2004; hereafter AWWW) names the separation of content, presentation, and interaction a good practice (§4.3). It names orthogonal and composable specifications a principle (§5.1). And it asks URI owners to provide representations of their resources (§3.5) — S4’s demand, minus the intermediates. All of it stated as SHOULD, because a recommendation can do no more than recommend. Hold that until Proposition 4.4: the separation the web’s own architecture group could only advise, the derivation forces; the addressing it could only request, the derivation constructs. The norms were theorems all along. AWWW is a witness here, never a premise: assuming §4.3 would be assuming this chapter’s conclusion, and the method forbids that.
The payoff of S4 is immediate and measurable. It is Fielding’s list: HTTP caching per stage rather than per page; crawlability of data rather than of renderings; intermediaries; independent evolution of the layers. The last of these will harden from a phrase into a proposition before the chapter ends. Every one will reappear in Part IV, scored against every architecture that forfeits it.
The analysis theorem
Prop. 4.4 (Analysis theorem). Every read whose output depends on State only through some finite part factors into the three stages with S1. The factorization then lifts to proper: realize each factor as a term of the languages Part III fixes in advance, give each stage’s output a URI, and S2–S4 hold. Finite dependence forces the shape; the lift is a construction the web always permits, never a consequence of finiteness.
The hypothesis is mild: a document renders finitely many facts, so every site ever deployed qualifies. Finiteness is there to make the proof’s minimal fragment well-defined; it excludes nothing real.
Proof sketch — take the minimal fragment the output depends on.
Define select(r, S) as a minimal fragment of S on which read(r, ·) actually depends — well-defined by finiteness; arrange and present are the induced quotients. That much is the analysis half: it gives S1 and the three-stage shape. S2–S4 are the lift. S2 is realization in languages whose semantics are fixed in advance and shared across applications, never invented around the read (which would make S2 vacuous). S3 is substitution within them, and S4 is publication, an act. The synthesis theorem (8.2) supplies all three. Full proof in Appendix B. ∎
Proposition 4.4 is what Chapter 3 was illustrating: stripping a real page is computing its proper factorization by hand. The theorem guarantees the exercise terminates for every site — including every site not yet built. And the note held from AWWW comes due: the separation §4.3 could only recommend, every read provably affords.
The debt to Fielding
The debt to Fielding runs deeper than the property list. REST was the last serious attempt to derive web architecture rather than fashion it: constraints applied stepwise, properties induced per constraint. That is the method this book inherits and pushes to theorem grade. But REST constrains the conversation and leaves the vocabulary open. It says how representations must transfer: statelessly, cacheably, through a uniform interface. It declines, deliberately, to say what a representation or the state behind it must be. That open question is this book’s subject. Chapter 5 closes it. That closure was unavailable to REST’s own method in 2000: the answer had been standardized only the year before. And the pressure that makes it visible — machines reading the web — was two decades out. Read this book as the second half of a derivation whose first half Fielding wrote.
His deepest constraint is also his least defined: the uniform interface. In Fielding’s own estimation it is the central feature that distinguishes the web from every prior architecture, yet he delivered it as four clauses of prose (§5.1.5) and never formalized it. “Uniform” is the quantifier: one signature for every application. That is why Definition 1.1 could open this book by fitting every web application ever built, and why Part V can close it with one application for every domain. The interface was always uniform; the state beneath it was not. Chapter 5 finishes the thought.
The four clauses, typed — one per component. (Borrows names from Chapters 5 and 7 and Appendix B; return here after the pipeline closes.)
| Fielding’s clause (§5.1.5) | typed here as |
|---|---|
| identification of resources | I — one name space; R3 (Chapter 5), S4 |
| manipulation of resources through representations | Definition 1.1 — read and write exchange representations; the delta normal form (Chapter 7) is the write’s |
| self-descriptive messages | self-containedness — B-2d, at the message’s scale |
| hypermedia as the engine of application state | the five moves (Chapter 7) — every transition a link in the document |
The four timelines
Definition 4.3 has one more consequence, and it can be collected now. Nothing in this chapter has mentioned time. HTTP has. A representation, per RFC 9110 §3.2, reflects “a past, current, or desired state of a given resource” — state at a time. And the protocol ships an apparatus whose only job is telling a resource’s representation at one moment from its representation at another: Last-Modified and ETag (RFC 9110 §8.8), and the caching calculus built on them (RFC 9111). The web’s own specifications already treat the document as a sequence of states; the time index comes ready-made. Index the moving parts — writing τ for time, since t is taken:
S : Time → State the world, over time
read_τ = present_τ ∘ arrange_τ ∘ select_τ the application, over time
doc(r, τ) = read_τ(r, S(τ)) what the user agent renders
Four components can move: the state S(τ) and the three factors. Each movement has a name you already know. The state advances when someone writes — Chapter 7’s whole subject. A factor changes only one way: by substituting its term — this is S3, read over time. The selection changes when a query is revised and redeployed, the arrangement when a layout switches or a template ships, the presentation when the theme changes.
And one thing that looks like movement is not: a user paging forward or tightening a filter changes nothing in the application. The filter travels in r, and select is the same term evaluated at a new argument. A model that makes the selection depend on time just to handle a mouse click has confused the function with its argument — a natural mistake, since the notation invites it. The four timelines belong to the application; navigation belongs to the request.
Prop. 4.5 (Independent evolution). In a proper factorization, the document’s evolution decomposes into four independent timelines, one per component (S, select, arrange, present): a change to any one component changes the document without requiring a change to, or the participation of, any other. In the fused factorization of Prop. 4.2 there is one component and therefore one timeline: every change, of whatever kind, is a change to the whole.
On the dashboard, that independence is one line of daily practice: ship a new theme and the panel data never re-fetches — present moved on its own timeline while S, select, and arrange stayed put on theirs.
Dependencies — S1 confines, S2 closes, S3 substitutes; proof in Appendix B.
Depends on 4.3: S1 confines a change’s effect to its factor’s output. S2 closes each term’s semantics, so substituting a term of one language cannot alter the meaning of a term in another. S3 guarantees the substituted term still yields a web application. Proof: Appendix B.
flowchart LR
subgraph proper["proper — four independent timelines"]
direction LR
S0(["S"]) -- "write" --> S1(["S′"]) -- "write" --> S2(["S″"])
q0(["select"]) -- "query revised" --> q1(["select′"])
x0(["arrange"]) -- "layout shipped" --> x1(["arrange′"])
z0(["present"]) -- "theme changed" --> z1(["present′"])
end
subgraph fused["fused — one timeline"]
direction LR
f0(["bundle"]) -- "any change" --> f1(["bundle′"]) -- "any change" --> f2(["bundle″"])
end
Prop. 4.5, drawn. In the proper factorization each component advances alone, and caches invalidate per component; in the fused one every change, of whatever kind, is a change to the whole — and invalidates the whole.
Prop. 4.5’s corollary is the first item on Fielding’s list — caching per stage rather than per page — now holding its mechanism. Under S4 each factor’s output is a resource; each resource has a URI; each URI carries its own validator — its own ETag, its own timeline, legible to every cache on the path. A theme change invalidates one stylesheet resource, and the data it styles stays cached at its own age, untouched. Collapse the factorization and there is one resource — the bundle — with one validator, and the corollary inverts: any change, of any kind, invalidates everything.
And the industry already operates all four timelines — one layer down. Fingerprinted stylesheets shipped with Cache-Control: immutable; data responses marked no-store; templates deployed on their own cadence. Every serious deployment on the web runs per-component timelines at the delivery layer, including deployments whose application architecture denies that the components exist. Independent evolution already runs in production, one layer below the framework that obscures it.
One thread left dangling, on purpose: select selects from State, and State is still abstract. The factorization cannot be completed until we know what it is a factorization over. That is Chapter 5, and it is where the book stops describing and starts forcing.