Backward-Compatible API Evolution
Backward-compatible API evolution preserves the contract existing clients rely on while the service changes. It requires considering client behavior and semantics, not just whether requests still reach the same endpoint.
Backward-compatible API evolution changes a service while preserving the assumptions existing clients rely on: routes, request and response shapes, meanings, and relevant operational behavior. Whether a change is compatible depends on how clients use the contract, not only on whether the server still accepts the same requests.
For a JSON API, adding an optional response field is often safe when clients ignore fields they do not recognize. Making a previously optional request field required, renaming a field, changing its meaning, or narrowing accepted values can break clients. Even an apparently additive change may fail with clients that reject unknown fields or depend on exact schemas.
Treat compatibility as a property to verify against real consumers. Maintain an explicit schema and behavior contract, use consumer or contract tests, and review changes to defaults, errors, ordering, and authorization as well as to field names and types. Roll out changes gradually when client adoption or runtime behavior is uncertain.
When a breaking change is necessary, introduce a clear migration path. This may involve a new API version, a transition period in which both forms work, usage monitoring, and a communicated retirement date. Versioning makes incompatible contracts distinguishable; it does not remove the need to migrate clients or manage deprecation.
Key points
- Preserve established request and response meanings, not merely endpoint names.
- Optional response additions are often safe, but strict clients may reject unknown fields.
- Changing requiredness, types, defaults, errors, or semantics can break consumers.
- Use contracts and consumer tests to detect incompatibilities before deployment.
- For necessary breaks, provide a distinct contract and a monitored migration path.
Interview questions
What does backward compatibility mean for an HTTP API?
Compatibility is about preserving the contract that existing clients rely on, including semantics and operational behavior, not just keeping an endpoint available. Adding an optional response field is commonly safe when clients ignore unknown fields. It is not guaranteed safe if clients enforce exact schemas. I would check actual consumer assumptions and validate the change with contract tests.
A field must change meaning. How would you evolve the API?
I would avoid silently changing the field's meaning, since clients may continue to parse it while producing incorrect results. If the new meaning cannot be represented separately, I would introduce a clearly distinguishable contract, often a new API version, and document a migration. During transition, both contracts may be supported and usage monitored. I would remove the old contract only after the announced deprecation process and migration criteria are satisfied.
How would you prevent an API change from breaking clients?
I would identify the consumers and capture their assumptions with schemas, consumer-driven contracts, or both. Provider changes would run against those checks in CI, including behavior such as defaults and error responses where relevant. I would also test compatibility in deployment, since configuration, authorization, or rollout order can break clients even when schema tests pass. Monitoring and a rollback plan help detect failures that tests miss.
When would you introduce a new API version rather than evolve the existing one?
Versioning is useful when clients need to select among incompatible contracts, but it creates parallel support and migration costs. I would first consider whether the change can be made additively or through a transition that preserves existing behavior. If a version is needed, its location and negotiation mechanism should be consistent and documented. I would plan support windows, telemetry, and retirement rather than treating the version label as the migration itself.