Writing the code first and documenting it afterward almost guarantees the documentation drifts out of date the moment anyone changes the code without remembering to update it too — contract-first design flips that order specifically to make drift structurally harder.
3 min read
Code-first: implement the endpoints, then write documentation describing what was built. Fast to start, but the documentation is disconnected from the code — nothing forces them to stay in sync, and in practice they drift apart the moment someone changes an endpoint without also updating the docs.
Contract-first: write a formal specification describing the API's shape before implementing it, then generate code, documentation, and client libraries from that one shared source of truth.
OpenAPI (formerly Swagger) is a machine-readable, YAML/JSON format for describing a REST API's every endpoint, parameter, request body, response shape, and error — precise enough that tooling can validate real traffic against it, not just display it for humans to read:
paths:
/users/{id}:
get:
summary: Get a user by ID
parameters:
- name: id
in: path
required: true
schema: { type: integer }
responses:
'200':
description: The user
content:
application/json:
schema:
type: object
properties:
id: { type: integer }
name: { type: string }
'404':
description: User not foundWriting a complete, accurate spec before implementation takes genuine time and discipline, and it's tempting to skip when moving fast on an early prototype where the shape is still actively changing. This is a real, reasonable trade-off, not a mistake — contract-first pays off most clearly once an API has (or will soon have) multiple consumers who need a stable, trustworthy contract; for a single team iterating rapidly on an early-stage internal API, code-first with good discipline about updating docs can be the more pragmatic choice, at least until the shape stabilizes.
A spec is also where lesson 8's consistent error shapes and System Design's versioning strategy become concretely enforceable rather than just documented intentions — the spec can declare exactly which error shape every endpoint returns and exactly what a breaking change to the schema looks like, letting tooling flag an accidental breaking change (a removed field, a changed type) automatically, before it ever reaches a real consumer.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What's the core difference between code-first and contract-first API design?
2. What can be generated directly from an OpenAPI specification, beyond human-readable documentation?
3. Why might a team building an early-stage, rapidly-changing internal API reasonably choose code-first over contract-first?
API Design