API Contract Testing in Practice
API contract testing verifies that the interface between a service provider and its consumers remains compatible as each evolves independently. It solves a fundamental microservices problem: how can we deploy services independently while being confident that the interfaces between them haven't broken?
Consumer-Driven Contracts
In consumer-driven contract testing (CDCT), consumers define the contracts — specifying exactly what they send to, and expect from, their provider. Providers verify they satisfy all consumer contracts. This means providers can't accidentally break consumers, and consumers can't make undocumented assumptions about provider behaviour.
Pact Framework
Pact is the dominant consumer-driven contract testing framework. Available for JavaScript, Java, Python, Ruby, Go, and more. The workflow: consumer writes a test that records an interaction (request + expected response) as a Pact file. The Pact file is published to the Pact Broker. Provider tests replay interactions against the real provider and verify the responses match. The Pact Broker tracks compatibility and enables "can-i-deploy" checks in CI.
Contract Testing vs Integration Testing
Integration testing requires both services running simultaneously — expensive and fragile. Contract testing is async and decoupled: consumer and provider tests run independently against recorded interactions. Contract testing doesn't replace integration testing entirely but dramatically reduces the scope of full integration testing needed.
GraphQL and gRPC Contracts
Pact supports GraphQL queries. gRPC services can use Protobuf schema as a contract — schema compatibility tools verify that proto changes are backwards compatible. Both work for the same fundamental goal: preventing incompatible interface changes from reaching production.