API Design · question
Question 80 of 110
What is API contract testing and how do you implement it?
Related concept
Testing APIs: three different questions
Three suites, three questions: behaviour, compatibility, capacity. The contract test is the one only an API needs.
For this question · chapter 2 of 3
2/3
The contract test catches it first
The contract test catches it first
- Of the four test layers, only an API needs the contract layer. Two teams each have their own repo and a passing build. The consumer, checkout-web, calls GET /orders/8842 and renders the response. The provider, orders-api, passes all 212 of its own tests, but nothing in its repo names a single consumer.
- Consumer driven means the specification is what a consumer uses, not everything the API happens to offer. Here the consumer's own test runs against a stub, which is a fake provider. The test records only what checkout-web read: id, total_cents, status and a 200 response. So the specification covers three keys out of the seventeen this endpoint returns.
- Both builds fetch the contract from a broker, so neither team has to ask the other for anything. The broker, a versioned file store between the two repos, is what makes contract testing work across teams. The consumer publishes its recording to the broker as version 4. The recording holds the request, the expected status code, and the three keys checkout-web needs in the body.
- The provider's build now checks every commit against what checkout-web actually reads. The build fetches the contract and replays it against the real orders-api, with orders-api's own dependencies stubbed. All three keys are there, so the check passes in 12 seconds, alongside the 212 tests the team already had. Pact is the tool most people mean when they say contract testing.
- No test in the provider's own suite can ever fail on this rename. The same people write the suite and the code, at the same time. So the commit that renames total_cents to amount_cents also updates the tests. All 212 provider tests still pass, so as far as the provider can tell, the commit is clean.
- The provider's build fails on the contract, which is the consumer's own recorded usage. Another team wrote that contract in another repo. The contract check expected total_cents but got amount_cents, so the build stops before deploy. Nothing shipped, so checkout-web is still reading total_cents.
- The cheaper option checks every response against your OpenAPI spec, with no broker and nobody to coordinate with. This check catches a response that stops matching the spec. But the check misses this rename, because the same commit also renamed the field in the spec. The spec is yours to change, but the contract belongs to the consumer.
Chapter 2 · step 1 of 7
Of the four test layers, only an API needs the contract layer. Two teams each have their own repo and a passing build. The consumer, checkout-web, calls GET /orders/8842 and renders the response. The provider, orders-api, passes all 212 of its own tests, but nothing in its repo names a single consumer.
© LearnThatStack - diagrams may not be republished without permission.
Want a quick review of the fundamentals? See the API Design cheatsheet.
Pro · $10/mo
90 of 110 API Design answers are in Pro.
Full answers, code samples, and AI explanations that go simpler or deeper. Cancel anytime.
- Full answers + code
- AI explanations, simpler or deeper
- 1,000 AI credits / month
- Cancel anytime