In my last post in the series of hypermedia API guidelines, I discussed the need to decouple the design and implementation details of your API from the constraints of any particular format. You likely aren’t designing your own format, but it is a good decision to avoid formats which require URL patterns, as they can provide confusion and increase the odds a consumer will make calls directly to URLs. In this post I’d like to go through the follow up guideline to don’t version anything, which will fill in the remaining gaps in dealing with resource and representation change. To support long term API flexibility, your design should leverage a strict non-breaking change policy, with a managed long lived deprecation process.
As time passes, an APIs design can lose relevance to the piece of reality it is built to model. Processes change, properties change, and priorities change so it is crucial to maximize flexibility for change over time. When using hypermedia APIs, it is important to understand the three types of changes you can make to your profile, and the appropriate way to manage each kind. Optional changes will make modifications to the representations and their actions without any effect on current consumers and their bindings. Required changes will make additions to the profile which can be gracefully handled by the generic client. Breaking changes, or removing items from the profile, will require a client update to maintain compatibility.
In traditional statically bound API styles the handling of the optional changes would likely lead directly to consumer client changes as the representations of resources are strongly coupled to the consumer. However, a generic hypermedia client is intentionally dumb when it comes to the properties of resources, so the addition of any unknown resource simply behaves in the default manner.
The story of required changes is much the same as the optional changes. The highly coupled service and consumer relationship requires constant maintenance and attention to continue to function. A hypermedia API consumer client will manage the required changes by standard approaches, generic fields which are required can be flagged to the consumer as invalid without requiring any strong bindings to the consumer client.
In this way, the two changes which represent any difficulty for hypermedia APIs are the required and breaking changes. In the case of the required changes, a previously valid representation is no longer valid because a new property has been added. Alternatively, there is a new action has been added to a representation which was not previously expected without a client binding to the action. The breaking change is a representation or action being removed from the profile which is has previously been required or bound by consumers. With these definitions, it’s clear the real difficulty is in addressing the breaking changes. The solution to breaking changes again can be found in the very first guideline I discussed, use the HTTP protocol to advertise change.
Previously in these discussions I have noted how the hypermedia API will manage the range of bounded contexts available to consumers. Diving into this concept a little further, the primary benefits in supporting a range of bounded contexts is to allow transparent incremental versioning and consumer preference in the resource representations to be utilized. Many leading tech organizations and methodologies stress the importance of versioning the API, unaware or uncaring of the fact that doing so has sown the seeds of future breaking changes. By tracking the changes of your representations in the supported vocabularies, your service is able to leverage the HTTP 3xx response code family to inform consumers that change is imminent while still respecting their interaction in the vocabulary they know. This allows consumers to upgrade gracefully on their own schedule, and greatly reduces the occurrence of high stress deadlines caused by your services’ evolution. Through nuanced activity tracking and API orchestration, you will have an accurate view on exactly when particular representations or portions of the API are no longer in use. Allowing you to confidently sunset old functionality knowing it will not likely result in a rude awakening to one of your extremely valuable customers.
By leveraging the protocol in the standard way, we can avoid breaking changes from immediately impacting consumers and requiring their full attention. As I’ve mentioned elsewhere, creating the good consumer experience is critical to the success of your API, and a great way to keep consumers happy with your service is to not break their clients at 3am on Saturday night.