LearnThatStack Ace your next interview
API Design · question
Question 80 of 110

What is API contract testing and how do you implement it?

expert Pro
← All API Design questions

The full answer covers the core mechanics, when this pattern wins, and the trade-offs interviewers most often probe. It includes a code sample. Read it once at your own pace, then try to recall the structure from memory before the interview. Pro also includes this question's interview lens - the likely follow-up probes and what you can say in the room.

Full answer + code samples + AI explanations

Unlock to read the complete answer for this premium question.

Guided practice for API Design One question at a time. Answer out loud, get graded, see what you missed.
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
contractsThe contract test catches it firstthe consumer's usage is the specprovider tests212passingcontractfailingcheckout-web3 of 17 usedcalls GET /orders/8842200 OKthe response it getsid"8842"customer_id"c-1140"total_cents3490currency"GBP"status"confirmed"placed_at"2026-08-19"channel"web"legacy_refnulland 9 more fieldstwo ways to checkone commit, two answersthe contractwritten by the consumerredit did not moveopenapi.yamlin the provider's repogreenit moved with the codeorders-apibuild redthe provider. its own repo, its own suiteits own test suite212 of 212the lighter option, on the same committhe schema check reads this repo's specthe commit renamed the field in bothso the spec and the response still agreepublishfailsthe provider can change its own spec. It cannot change the consumer's contractschema validation is still worth having when every consumer is yours
contractsThe contract test catches it firstprovider tests212passingcontractfailingcheckout-web3 of 17 usedcalls GET /orders/8842200 OKid"8842"total_cents3490currency"GBP"status"confirmed"placed_at"2026-08-19"and 12 more fieldstwo ways to checkthe contractwritten by the consumerredopenapi.yamlin the provider's repogreenorders-apibuild redthe lighter option, same committhe schema check reads this repothe commit renamed bothspec and response still agreeit can move its spec, not their contract

The contract test catches it first

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.

1 of 7 Use ← → or swipe See the concept: all 3 chapters in it

© LearnThatStack - diagrams may not be republished without permission.

Want a quick review of the fundamentals? See the API Design cheatsheet.

← Back to all API Design questions
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