patterntypescriptMajor
Contract testing with Pact: consumer-driven contracts prevent API drift
Viewed 0 times
pactcontract testingconsumer drivenmicroservicesapi driftpact broker
Problem
In a microservices architecture, a provider API changes a field name or type and the consumer breaks in production. Integration tests in CI catch this only if both services are deployed together, which is often not the case.
Solution
Use Pact for consumer-driven contract testing. The consumer writes a test that defines exactly what shape it expects from the provider. Pact records this as a contract file (pact JSON). The provider runs a verification step against the recorded contracts in CI. If the provider breaks a contract, CI fails before deployment.
Why
Consumer-driven contracts encode the consumer's actual usage, not the full API surface. Providers know exactly which consumers use which fields and can safely evolve unused ones. Contracts can be stored in Pact Broker and queried by version.
Gotchas
- Pact tests are not a substitute for integration tests — they verify shape, not behavior
- Both consumer and provider must commit to running Pact verification in CI or the system breaks down
- Pact Broker webhooks can trigger provider verification automatically when a new consumer contract is published
- Non-HTTP protocols (gRPC, GraphQL) need the pactflow plugin or custom matchers
Code Snippets
Consumer Pact test with PactV3
// Consumer test (Jest + @pact-foundation/pact)
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
const provider = new PactV3({
consumer: 'web-app',
provider: 'user-service',
});
it('fetches a user', async () => {
await provider
.given('user 42 exists')
.uponReceiving('a GET request for user 42')
.withRequest({ method: 'GET', path: '/users/42' })
.willRespondWith({
status: 200,
body: {
id: MatchersV3.integer(42),
name: MatchersV3.string('Alice'),
},
})
.executeTest(async (mockServer) => {
const user = await fetchUser(mockServer.url, 42);
expect(user.name).toBe('Alice');
});
});Revisions (0)
No revisions yet.