DEV Community

alexrai
alexrai

Posted on

Mocking Your API Before You Build It Reveals Bad Design Early

Most teams reach for mocking after an API exists, as a way to test against it without calling the real thing. That is useful, but it misses the most valuable moment to mock, which is before the API is built at all. A mock written first is not just a testing convenience. It is the cheapest possible prototype of your design, and it tends to expose bad decisions while they still cost nothing to change.

A mock is a design you can actually try

An API design usually lives in a document or a diagram, and documents hide problems. Everything reads fine on the page because the page never has to actually respond to a request. The moment you turn that design into a mock, something changes. Now you can send it real requests and get real responses back, and the awkwardness that a written spec conceals becomes obvious the first time you try to use it. A mock is the difference between describing a design and experiencing it, and experiencing it is where the flaws show up.

Using your own design is the fastest critique

The most honest test of an API is what it feels like to write a client against it. When you mock the API first and then build a small client that consumes the mock, you are the first user of your own design, before a single line of the real implementation exists. Good api mocking tools make standing up that mock quick enough that this becomes a normal early step rather than a special effort. Within an hour of consuming your own mock, you notice the response that forces three follow up calls to be useful, the field that is technically present but painful to work with, the endpoint that returns everything except the one thing the caller actually needs. None of that is visible in a spec. All of it is obvious the moment you have to use the thing.

Fixing design in a mock costs nothing

The reason this ordering matters so much is economics. Changing an API design that only exists as a mock is trivial. You edit the mock and move on. Changing that same design after it has been implemented, deployed, and picked up by three consuming teams is a migration project with a deprecation window and a lot of unhappy conversations. The defect is the same in both cases, a design that does not serve its callers well, but the cost of fixing it differs by orders of magnitude depending on when you catch it. Mocking first pulls that discovery to the cheapest possible point in the timeline.

The contract gets negotiated before anyone commits code

There is a coordination benefit that compounds the design one. When the mock comes first, the teams that will produce and consume the API have something concrete to argue about before either side has built anything. The consumer builds against the mock, hits the rough edges, and asks for changes while changes are still free. The producer learns what the consumer actually needs rather than guessing. By the time real implementation starts, the interface has already survived contact with a real user, which is exactly the validation a design most needs and most rarely gets before it is set in code.

What this asks of you

This approach is not free of discipline. It asks you to treat the mock as a genuine design artifact, to actually consume it rather than admire it, and to take the friction you feel seriously instead of dismissing it as something the real implementation will smooth over. It will not. If the design is awkward against a mock, it will be awkward against the real thing, because the awkwardness is in the interface, not the implementation. The mock is only useful here if you are willing to let it tell you uncomfortable things about a design you were already attached to.

Keeping the mock honest once building starts

Once the design settles and real implementation begins, the mock does not retire, it changes jobs. It becomes the contract both sides continue to build against, and the thing the real implementation must be verified against as it grows. The design first mock and the running service should be checked for agreement continuously, so that the moment the implementation drifts from the interface everyone validated, someone finds out early. The mock that started life as a design prototype becomes the reference that keeps the real service honest, which is a lot of value from an artifact that took an hour to create.

Where this leaves me

Mocking after the fact is fine, but mocking first is where the leverage is. A mock built before the implementation is the cheapest prototype of your API you will ever make, and using it as your own first client surfaces bad design at the one moment it is still free to fix. Build the mock, consume it yourself, let it embarrass the design while embarrassment is cheap, and only then write the real thing against an interface that has already proven it works for its callers. Do it in that order and you avoid the most expensive kind of API mistake, the one you only notice after everyone is depending on it.

Top comments (0)