Why this matters
Integration failures often appear late because providers and consumers are tested separately. Contract tests make the expectations at the boundary explicit: fields, types, required values, status codes and compatibility rules.
They do not replace integration testing, but they provide a fast signal when one side changes something the other side depends on.
How to do it well
Identify real consumers
List which services, jobs and external clients use each endpoint and which fields they rely on.
Capture expectations
Define request and response schemas, optionality, error behaviour and semantic rules.
Version the contract
Store OpenAPI, JSON Schema or consumer contracts alongside code and review changes.
Run consumer checks early
Verify that the consumer can create valid requests and interpret representative responses.
Verify the provider in CI
Confirm that the provider satisfies all supported consumer expectations before deployment.
Plan compatibility
Use deprecation periods, additive changes and clear migration paths for breaking changes.
What to avoid
- Assuming that valid JSON means a compatible response.
- Treating every field as required when consumers do not need it.
- Changing enum values or meanings without considering semantic compatibility.
- Maintaining contracts manually but never executing them.
- Using mocks so unrealistic that integration risks remain hidden.
Practical example
If an audience API changes an identifier from number to string, a provider unit test may still pass. A consumer contract immediately reveals that the downstream import expects numeric comparison.
An additive field is usually safe, while removing a field requires evidence that no supported consumer depends on it. The contract history makes that decision visible.
Lesson for practice
Contract testing moves integration feedback closer to the change. Its value comes from explicit expectations, executable verification and disciplined compatibility—not from schema files alone.
A good practice does not have to be complicated. It should be intentional, repeatable and explainable: the team should understand why the control exists, what evidence it provides and how feedback will improve the next iteration.
