Consumer-driven contract tests
Catch a breaking API change inside the provider build instead of in production.
Open this lesson in the learning hubKey points
- Integration testing every pair of services does not scale. A contract pins only the shape each consumer actually depends on.
- The consumer states what it needs. The provider build replays that contract against the real controller on every commit.
- Rename a field a consumer reads and the provider build goes red, so the break never reaches a deployment.
- Spring Cloud Contract keeps contracts in the provider repo and generates its tests and the consumer stubs. Pact is the polyglot option.
- Contracts check shape, status and headers, not business rules. They replace cross-service integration tests, not your unit tests.
Example
# contracts/shouldReturnOrder.yml - lives in the PROVIDER repository.
description: an order can be fetched by id
request:
method: GET
url: /v1/orders/o-1042
response:
status: 200
headers:
Content-Type: application/json
body:
id: o-1042
status: PLACED
totalCents: 4999 # rename this field and the provider build fails
matchers:
body:
- path: $.totalCents
type: by_type
# Provider build: the plugin generates a test that calls the real controller.
# Consumer build: the same file is published as a WireMock stub, used with
# @AutoConfigureStubRunner(ids = "com.example:orders:+:stubs",
# stubsMode = StubsMode.LOCAL)
Let the consumer say what it needs, then make the provider build prove it still holds.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Microservices course, and every lesson in it is listed on the Microservices contents page.