sommai - Fotolia
Service interfaces inevitably change over time. Despite much effort and research, it's difficult to create the perfect interface with version 1.0. Fortunately, it's not difficult to handle the inevitable API versioning decisions that must be made.
API versioning is more of a process problem than a technical one. From a technical standpoint, versioning is straightforward. It needs to be determined whether changes result in a backward-compatible interface. A backward-compatible interface is one where messages still work when coming into an updated API based on the previous version, and response messages from the API should still work when sent back. The term should is used because API consumer actions with response messages can't be controlled.
Normally, the following changes to a request are considered backward compatible:
- Adding endpoints (e.g., a new REST resource)
- Adding operations to an existing endpoint (e.g., when using SOAP)
- Adding optional fields to the request interfaces
- Changing a mandatory field to optional in an existing request interface
- Adding fields to a response (whether optional or not)
Typically, the following changes to a request are not considered backward compatible:
- Adding a new mandatory field to the request interface
- Making a previously optional field in the request mandatory
- Removing fields from the request or response (as opposed to making it optional)
- Making a previously required response field optional
- Changing the structure or relationship between fields (e.g., making an existing field a child of some other field) in either the request or response
If an interface is backward compatible, it may be best to make changes in place. Existing consumers should continue to work as is; why make work for them if it's not necessary? Why create the potential for running multiple versions in production if they're not needed?
Decisions need to be made if the new interface is not backward compatible. The easiest approach is to create a new endpoint, such as adding a version identifier in the URL. Existing endpoints can be kept, but only if something in the request can clearly indicate the version expected. For example, a custom HTTP header can be used to always specify the version number associated with the message, and then you can rely on the implementation to route the request accordingly.
This is where an API management system or networking infrastructure comes into play. A gateway is a common feature of most (if not all) API management platforms. The gateway should be where the version and route to the appropriate API implementation are determined. A common challenge, however, is that version 1.0 may not have leveraged a router, so now a spot to insert a router into the mix needs to be found. In most cases, this can be done without changing the endpoint visible to the consumer; but depending on how the API is architected, it could be a complex change.
Using transformation for API versioning
Transformation is of value only when you're getting rid of an older implementation. If you're running old implementations, simply route the request to the correct one. However, once an old implementation is turned off, the only choices are to reject the request or transform the request into something a more recent version can handle.
Transformation can handle only a small subset of the cases. A mandatory field can't be added that isn't there with a transformation. However, most situations can be addressed where the necessary information is there but it's not in the right structure or format. It must be decided whether an old implementation should be run.
If an old implementation is run, it can be good for an API's existing consumers, who aren't forced to make changes unless a new capability or information is needed. On the downside, running an old implementation is more costly. The more versions supported, the more complicated the gateway logic will be. It also sets a precedent that APIs are never turned off.
Every situation is different, and how they're handled comes back to the point of the second article in this series: Know your consumer. If you need to bend over backwards when you're dealing with customers, you may have to do everything possible to avoid making them change. If customers have good maintenance practices and make regular updates that encompass both new features and upkeep functions, then retiring old versions may be more palatable to them.
This is also why a solid consumer portal should be a fundamental part of an API management strategy and part of evaluation criteria for an API management solution. How often do customers review API documentation, release notes and sample code? How many make it a regular habit? An API management offering can be a key tool for communicating with customers.
The four articles in this series on API design, along with the previous series on API management tool capabilities, offer solid best practices for getting APIs off on the right foot and for making sound decisions throughout their lifecycle.
About the author:
Todd Biske is an enterprise architect with a Fortune 50 company in the St. Louis metro area. He has had architecture experience in many different verticals, including healthcare, financial services, publishing and manufacturing, over the course of his 20-year career.
Learn about using the Semantic Versioning specification for API versioning