/writing
Mocking the API Contract Before Implementing It
· 3 min read
When backend and frontend build the same feature, the frontend waits. Everyone agreed the API shape on a whiteboard, but until the endpoint returns something, nobody can wire the UI to it. So the frontend writes mocks, the mocks drift, and “we agreed on the shape” stops meaning much once the real thing lands looking slightly different.
I started shipping the contract before the implementation. The endpoint goes to production early, returns a realistic example payload, and serves the agreed OpenAPI shape before any real work happens behind it.
This is one piece of the dashboard’s integration layer. Contract-first mocks sit at the boundary between teams, before the codegen pipeline or the proxy layer ever see the spec.
The contract is the decision
The shape of an API is the part worth arguing about: field names, types, what is optional, how a list differs from a single item, how errors come back. Once those are settled, the implementation behind them is just engineering. The implementation can change later. The contract is what the frontend, the SDK consumers, the docs and the SLA all depend on.
Treating the contract as the output of the design phase changes the order of work. Design, build, expose becomes design, expose, build.
Alternatives considered
This meant rejecting three patterns the team had already tried.
Wait for the backend. The default. Frontend work blocks on backend work even when everyone agrees on the contract. That delay is the whole problem, and being patient about it does not make it smaller.
Frontend-local stubs. Everyone writes their own mock for whatever they need to render today. The stubs drift from each other and from reality, and by the time the real endpoint lands there are three code paths for the same data to reconcile.
Types only. Publish the TypeScript types from the spec and leave the endpoint for later. You can compile against types, but they do not return data. QA, integration tests and screenshots all still wait.
A mocked endpoint gives you what each of those was reaching for at once: a real URL, real types and realistic payloads, in production from day one.
Realistic examples beat empty stubs
An endpoint returning an empty list is technically a contract and practically useless. The frontend cannot tell whether the rendering is right, because the data does not look like data. QA cannot test edge cases, because there are none.
An endpoint returning a realistic payload is a different thing. It looks like what you will actually get. Schema generators consume it and docs tools render it as a sample response. The same examples end up in the spec, the mock and the documentation, from one source.
A marker for what is real
The catch is that a consumer cannot tell a real endpoint from a stub returning canned data. So each endpoint carried a small marker showing its implementation status. Mocked ones appeared as mocked in internal dashboards, and CI refused to call an endpoint done until the marker came off.
It did one boring job well. It made the difference between “returns 200” and “does what it says” visible to everyone.
What I learned
The delay between backend and frontend is real but mostly self-imposed. Ship the contract first, even as a mock, and the problem turns into scheduling. The frontend builds against the real URL, the backend implements at its own pace, and the day the implementation lands the frontend already works.
More writing
Proxy Patterns for Multi-API Dashboards
How I designed a proxy layer to unify multiple APIs with different auth, error shapes, and data models behind one type-safe surface in a React dashboard.
· 3 min read
One Source of Truth for Fair-Usage Limits
A pricing policy is only as real as the number of systems that agree on it. Nine published usage bands, one table, and three codebases reading it.
· 4 min read
Building Type-Safe APIs with OpenAPI
How the dashboard API integration layer became its own product: OpenAPI as the single source of truth across multiple consuming teams.
· 4 min read