How to use this book
Every other notebook in this series is about making something work. This one is about making something understandable, which is harder, because the person who has to understand it is not in the room and never will be.
You will design an API once and then answer questions about it for two years. The questions arrive as Slack messages from a frontend engineer, as bug reports from a partner integration, as a support ticket from a customer whose retry loop created four hundred duplicate orders. Every one of those questions is a place where your interface failed to say something, and a human had to be paid to find it out instead.
The one question
What can they work out without asking you?The lecture behind this book is Complete REST API Design
(youtube.com/watch?v=RG6q57DwV8Y, 2h04), and it names the problem exactly once,
at 48:30. If you do not follow a standard, the only two ways anyone can learn
your API are to read your source code or to try things until something works.
Both are expensive. Both produce wrong assumptions that ship.
Everything in this book is one more thing they no longer have to ask you:
| Part | What they get for free, if you get it right |
|---|---|
| I | Why any of this is standardised at all |
| II | What the thing is, and what contains it |
| III | Whether it is safe to send twice |
| IV | What just happened, and whose fault it was |
| V | What comes back when they send nothing |
| VI | The one operation your nouns cannot express |
| VII | Every endpoint after the first |
If you can say, for any design decision, what it tells the consumer and what it leaves them guessing, you can answer almost any API design question in an interview, including the ones about standards this book does not cover.
What this book is not
It is not about HTTP. Notebook 11 covers the protocol: what a header is, how a
connection is established, what actually travels on the wire. This book assumes
all of that and asks a different question about the same machinery: given that
PATCH exists, when is choosing it the right design decision, and what does
choosing it promise? Where the two touch, this book points across rather than
repeating badly.
It is also not about your framework. There is no routing code here, no ORM, no controller. The lecture is emphatic about this and it is right: an API is designed before it is programmed, and the design outlives the language you first wrote it in.
The five block types
| Block | What it means |
|---|---|
| Interviewer asks | A real follow-up you should expect. Answer it out loud before reading on. |
| Senior signal | The specific sentence that separates a senior answer from a mid-level one. |
| Trap | A common answer that sounds right and is wrong. |
| Do this | The concrete practice, with the parameter or the number. |
| Key idea | The one thing to carry out of that section. |
The four highlighters
Colour is never decorative here. Each one means one thing, so a marked phrase is already half-read before you reach the words.
| Mark | Means |
|---|---|
| peach | The sentence to carry away |
| rose | The wrong answer, the thing that bites |
| mint | The correct practice |
| pink | A definition, at the point it is first defined |
What is in the lecture and what is not
Parts I, II, III, VI and VII are the lecture, expanded, with the specification put back where it hand-waves. Part IV is roughly a quarter lecture: it covers four status codes, and the other seven in that part are the ones interviews actually ask about. Part V corrects the lecture directly, because the pagination it teaches has a bug that appears the moment two people use the system at once.
Where a claim in the lecture is wrong, this book says so, in a trap block, with the specification reference. There are four of them.
A suggested route
- Read Part I once and do not memorise it. It exists so that section 41 lands.
- Parts II and III are reference. Read them with an API you have shipped open in another window, and mark every rule you broke.
- Part IV is the highest interview yield in the book. Drill the codes until you can place any of the eleven without thinking.
- Part V is the one to work with a pen.
The whole picture on one page
One endpoint. Every decision in this book is visible in it.
CLIENT SERVER
│
│ POST /v1/organizations/8f2a/archive
│ ──── ── ───────────── ──── ───────
│ 1 2 3 4 5
│
│ Content-Type: application/json 6
│ Idempotency-Key: 7c1e-44b9 7
│ If-Match: "v8" 8
│
│ { "reason": "merged into 3d10" } 9
│ ─────────────────────────────────────────────────▶ │
│ │
│ ◀───────────────────────────────────────────────── │
│ │
│ 202 Accepted 10
│ Location: /v1/jobs/44 11
│ ETag: "v9" 12
│
│ { "id": "8f2a", "status": "archiving" } 13
│Thirteen decisions, and each one is a question the consumer does not have to ask:
| # | The decision | What it tells them, for free |
|---|---|---|
| 1 | The method | Whether a retry is safe. Nothing else says this |
| 2 | The version | That you will not break them without warning |
| 3 | The collection, plural | That there are many of these, and this is one namespace |
| 4 | The instance | Which one. Opaque, so its format is not a promise |
| 5 | The action, last | That CRUD could not express this, and a verb was needed |
| 6 | The content type | How to parse the body, and which patch dialect |
| 7 | The idempotency key | That a timed-out retry will not act twice |
| 8 | The precondition | That a concurrent edit will be refused, not silently lost |
| 9 | The body | Only what the server cannot work out itself |
| 10 | The status code | What happened, and whose fault it was |
| 11 | The location | Where the thing that was made now lives |
| 12 | The validator | What to send back on the next write |
| 13 | The representation | The new state, so no follow-up read is needed |
Four rules are encoded in that picture, and they are the whole book.
- The interface must carry the answer, or a human will carry the question. Every line above replaces a Slack message.
- Consistency beats correctness, and it is not close. A consumer who has integrated one of your endpoints has already guessed the rest. Being uniformly unusual costs them one lookup. Being occasionally standard costs them all of them.
- Defaults are part of the design. Sending nothing must work, and what comes back when they send nothing is a decision you make once for everybody.
- The method and the status code are the only two things every intermediary understands. Proxies, caches, retry libraries and load balancers read those and nothing else. Get them wrong and machinery you never wrote will do the wrong thing on your behalf.
Part I · The standard exists so you do not have to negotiate
1The requirement: an interface two strangers agree on
You are building a project management platform. Organisations contain projects, projects contain tasks. Think of Jira or Linear with the ambition removed.
The backend is yours. The web client belongs to a frontend engineer two desks away, the mobile client belongs to a contractor in another timezone, and in six months a customer's integration team will connect their own systems to it without ever speaking to you. Those three groups will never read your source code. The interface is all they get.
Now consider what happens if you design it carelessly. Say you used POST where
a PUT belonged, called one field description and another desc, returned
404 for an empty search result, and named one collection /organizations and
another /project. Nothing here is a bug. Every endpoint works exactly as you
intended.
The lecture puts the consequence plainly at 48:30. Someone integrating that API has only two ways to discover how it behaves:
1. read your code requires access, and the ability to read
your language, and time you did not budget
2. call it and observe requires guessing, and every guess that
works becomes a permanent assumptionBoth are expensive, and the second one is worse than it looks, because an assumption that happens to work is indistinguishable from documentation until the day you change the behaviour it was resting on.
The standard is the alternative to the conversation. If you follow the same
conventions everyone else follows, the consumer arrives already knowing most of
your API. They know the collection is plural. They know GET will not change
anything. They know 201 means something was created and 404 means it was not
found. You spent none of your time and none of theirs establishing any of
that.
That is the entire economic argument for standards, and it is worth stating in one line because interviews ask for it:
Part I · The standard exists so you do not have to negotiate
21990 to 1993: the web outgrows its inventor
In 1990, Tim Berners-Lee started a project to share documents between researchers. Within about a year, that project had produced six things, and you are still using all six:
1. the URI a name for a thing, that anyone can write down
2. HTTP the rules for asking for it
3. HTML a format for what comes back
4. the web server the thing that answers
5. the web browser the thing that asks
6. an HTML editor built into the browser, and the one that did not lastThat sixth one is worth a moment. The original browser could edit the page you
were reading and write it back. The web was designed to be read and written
symmetrically, and it took about thirty years and a great deal of JavaScript
to get back to something resembling that.
Then it grew, and growth was the problem. The design assumed a research network. What arrived was the public, in numbers nobody had planned for. By 1993 the project was heading toward breakdown, not because any single piece was wrong, but because nothing in it had been designed for the number of participants it suddenly had.
Roy Fielding, then co-founder of the Apache HTTP server project, was working on exactly this problem. His question was not "how do we make the server faster". It was structural: what properties must it have so that new pieces, written by people who never coordinate, can be added without the whole thing falling over?
His answer was a set of constraints. Not features, constraints: rules about what components are not allowed to do, chosen so that useful properties fall out for free.
Two things came out of that work. Fielding and Berners-Lee co-authored the specification for HTTP/1.1, the first version of the protocol that was really engineered rather than invented. Then, in 2000, Fielding wrote his doctoral dissertation, which did something unusual: rather than proposing a new architecture, it described and named the one the web had already become.
He called it Representational State Transfer, or REST.