Breaking Contract Changes
A breaking contract change invalidates assumptions that one or more existing consumers rely on at a system boundary. Contract tests make selected expectations executable, helping teams detect incompatibilities and manage migrations.
A contract describes assumptions at a system boundary: for example, an HTTP endpoint’s method, path, status codes, request fields, and response shape. In contract testing, consumers and providers use these expectations to check that their interaction remains compatible.
A change is breaking when a consumer that worked against the previous contract can no longer rely on the same behavior. Examples include removing a response field, changing its type, making an optional request field mandatory, or changing an endpoint’s meaning or error behavior.
Whether a change breaks compatibility depends on actual consumer assumptions. Adding a response field is often safe for consumers that ignore unknown fields, but can break consumers that reject them. A change that looks additive is not automatically safe.
Consumer-driven contract testing captures expectations from consumers and checks that the provider satisfies them. Provider verification can run in CI, helping teams find incompatibilities before deployment. It complements, rather than replaces, unit, integration, and end-to-end tests.
When a breaking change is necessary, teams can coordinate a migration: introduce a replacement behavior, allow consumers time to move, monitor usage, and remove the old behavior only when it is safe. Versioning can help communicate incompatible changes, but does not by itself ensure consumers have migrated.
Key points
- A breaking change invalidates an assumption relied on by at least one existing consumer.
- Compatibility depends on consumer behavior; even additive changes can be breaking.
- Consumer-driven contracts encode expectations and let providers verify them.
- Contract tests detect only incompatibilities covered by the recorded expectations.
- For necessary breaks, plan communication, migration, adoption checks, and removal.
Interview questions
What makes an API contract change breaking?
A breaking contract change invalidates an assumption made by an existing consumer. For example, removing a required response field or changing its type can break code that reads it. Whether a change is breaking depends on consumer behavior: adding a field may be safe for tolerant consumers but unsafe for strict schema validators. I would check the contract and known consumers before classifying the change.
How does consumer-driven contract testing help prevent breaking changes?
In consumer-driven contract testing, a consumer publishes expectations about interactions it uses, and the provider verifies that it can satisfy them. The expectations might cover request matching, status codes, and response fields. This gives fast feedback about compatibility without requiring every consumer and provider to be deployed together. It only checks behaviors represented in the contracts, so other testing is still needed.
How would you roll out a necessary breaking API change?
I would first identify the affected contract and consumers, then determine exactly which assumptions the change invalidates. If possible, I would introduce the new behavior while preserving the old one, communicate a migration path, and use telemetry or consumer reports to track adoption. I would remove the old behavior only after confirming it is no longer needed and following the service’s deprecation policy. A version bump can signal incompatibility, but it does not migrate clients by itself.
Why can adding a response field still break a consumer?
An additive change is often compatible when existing consumers tolerate fields they do not use. It can still break consumers that validate an exact schema, deserialize into a rigid model, or treat unexpected data as an error. I would inspect consumer contracts and validation behavior rather than assume that adding data is harmless. Provider verification against real consumer expectations can expose this kind of risk.