Chapter 1. What the Web Is

Vague but exciting…

— Mike Sendall, on Tim Berners-Lee’s 1989 proposal

Nothing in this chapter is mine. That is the point of it.

The web ships with its own definitions, and they are shorter than you probably expect. There are identifiers:

I     the set of URIs                                    (RFC 3986)

There are requests, which are built from identifiers:

Req = I × Method × Headers × Body                        (RFC 9110)

The body may be empty; the empty body is a body, the way an empty set is a set. Requests with a safe method — RFC 9110’s word for the methods that only ask, never change — almost always leave it empty. The unsafe methods are about to show what it is for. (RFC 9110’s own name for it is content — a word this book will need for something else, so the older wire name stays.)

Responses come back the same shape, because RFC 9110 defines one message form for both directions. A status code stands where the method and identifier stood:

Resp = Status × Headers × Body                           (RFC 9110)

Of the response, the definition below keeps only what the body carries. The body itself is octets. A header names their format (Content-Type), and the format’s specification — not this book — defines how they parse. On the parsed side of that line lives the document — the thing a user agent displays. Call that domain Doc, and leave its internals alone for now. The envelope around it — the status code, the response headers — is how a document travels, ages, and caches. That is transfer machinery, and Definition 1.1 will not mention it.

Definition 1.1. A web application is a pair of functions:

read  : Req × State → Doc
write : Req × State → State

This is HTTP restated. read is what the safe methods do — GET takes a request and the current state of the world and produces a document. write is what the unsafe methods do — POST, PUT, PATCH, DELETE take a request and a state and produce a new state. The request’s body carries what the change should be. The body belongs to the write side: on a safe request it has no defined meaning (RFC 9110 §9.3.1), and read ignores it. read’s output travels in the response’s body instead. Like Doc, Body stays opaque for now; Chapter 7 says what fills it.

Every web application you have ever used, from a static homepage to the heaviest single-page monster, implements these two functions, because HTTP gives it no other way to be an application on the web. The framework it was built in is an implementation detail of Definition 1.1.

Notice what the definition does not say. It does not say what State is. That omission is deliberate, and it is the engine of this book. Definition 1.1 is a question stated as a definition: what must State be? Part II is the answer, and the answer will be forced, not chosen; Part III names it.

Prop. 1.2. Every deployed web application implements Definition 1.1. (Verification: RFC 9110 §9; there is no third kind of method.)

Prop. 1.3. Definition 1.1 constrains architecture not at all. Both a 1993 CGI script and a 2026 React application inhabit it. (This is why the definition is safe as an axiom — no one on any side of any framework war can reject it.)

The standing connection. One apparent counterexample is worth settling while the definition is fresh. WebSockets and server push carry traffic that is neither a safe nor an unsafe method — no method at all. The applications built on them — the live dashboard, the collaborative editor — can look like a third kind of thing. They are the same two functions at a different rhythm. Whatever flows on such a channel is one of two things: read’s output, arriving as the state changes rather than when it is requested, or write’s argument, arriving without a fresh envelope. Either way, the typing of Definition 1.1 is unchanged. What the channel sheds is not the definition but HTTP’s machinery around it: methods, caches, a URI per exchange. Each shed piece has a cost. Part IV computes those costs one by one, under the names Chapter 5 gives them. (Part II will even name the standing connection’s honest cargo: change turns out to have a normal form, and a stream of it is something a machine can read.)

The chapter closes with a reading of the web’s history that the rest of the book will substantiate. The web succeeded against its contemporaries: Gopher, BBSs, desktop applications, and Java applets, an experiment Chapter 12 reruns. It succeeded because its read was transparent, legible to machines that did not produce it. Documents were declarative, addressable, linkable, indexable. Every technology audited in Part IV will turn out to be a position on exactly one question: how transparent is your read? But no audit can begin, and no history can be checked, while Definition 1.1’s omission stands. And how to fill that omission honestly is a question of method — answered by neither a survey of the industry nor the author’s taste. The method is old, it has a name, and it is the next chapter.