Using Canary Release To Ease API Versioning

One of the greatest struggles an API provider can face is how to manage versions and builds from instance to instance. The constant need to iterate matched with the constant need to organize has made versioning a controversial and often discussed facet of modern API development. There are some alternatives to traditional versioning, however, that grant some major benefits.

Today, we’re going to discuss one of these solutions — canary release. Canary release has quickly become a huge component of transparent API development, and for open banking, it is perhaps one of the best tools modern financial institutions can leverage for transparent, effective version control without breaking foundational interoperability.

This piece was inspired by Patrice Krakow’s talk A Journey from API Versioning to Canary Release from the Nordic APIs 2017 Summit. Watch below, and view slides here.

Why is API Versioning and Canary Release So Important?

At times, there can be a certain tension between API providers and API consumers. The API provider may want to change the API as they get new, greater ideas. These ideas are promising, showing new features, new methodologies, and possible new directions for the API.

However, the API consumer often just wants something stable. Unless the consumer is interested in that new, great idea, consumers want the API to function predictably.

This creates a clear and obvious struggle, and is chiefly the reason why versioning is so difficult for many users. Perhaps the best argument against versioning, though, is from Roy Fielding, the father of REST design. His opinion on implementing versioning? “Don’t.”

Read more on versioning types: Introduction to API Versioning Best Practices

What is Versioning?

Why, specifically? Why shouldn’t we do versioning as a matter of course? Let’s take a look at the repercussions of versioning APIs.

Versioning is the idea that as features get added to a service, this fundamentally creates a new version of the existent objects. These versions are distinctly different, and often function entirely separately with different purpose, and as such, are treated as distinctly separate developments.

In traditional versioned development, these new versions would be marked in small movements as beta releases for testing, and as landmark releases for complete improvements. Once testing is underway, typically in an opt-in fashion, these beta releases will slowly be moved towards candidate releases, and then actual versions.

This type of versioning has some major benefits, chief of which is the fact that major improvements in form and function are clearly demarcated. This ability to demarcate is very important, especially when working with different hardware versions, but ultimately, this in itself is the downfall of the versioned approach. Many users will know the pain of attempting to use a device only to find that their firmware, software, or other element is incompatible and requires updating. Thus, they don’t use the system, and return at a later date to find that the situation is even worse.

This ultimately leads to a massive division in userbase of updated and non-updated, and puts far too much importance on singular instances rather than the holistic system itself.

What is Canary Release?

Canary release is a technique that seeks to alleviate many of these negatives. Canary release is often positioned as an alternative to versioning, like versioning lite.

In canary release, the risk of introducing new software is mitigated by first slowly rolling out these changes to small subsets of users, instead of rolling them out via opt-in and later forced release as in classic versioning. These small subsets of users test the new version through dynamic load balancing, and once the versioning is verified to function as desired, the new version becomes the default.

We call this canary release because it functions akin to a canary in a mineshaft. A canary was once used by miners to test the air in a mine. If the air was poisonous, the canary would die, signaling to the miner that they had to leave immediately. In the same way the canary dies in the mine, if the API instance being slowly tested is bad, it will be detected due to the failures in the small subset rather than massive failures to the general audience.

The application is calling an instance of a service tied to an API – and as these requests are gradually exposed to the new version, specific applications, hardware, methods, and more can be dynamically and granularly tested against the new version. Eventually, if all goes well, everything will go to the new version, the old version will be deprecated, and the users will be none the wiser.

A huge benefit here is the fact that rolling back is easy – ultimately, you just stop sending requests to the new canary instance and just send it to the old one.

ING Versioning

This approach is easier to understand once you see it in action. Patrice Krakow gave a talk on canary release at the 2017 Nordic APIs Platform Summit, in which he provided the following workflow as an example of how ING Bank handles canary release.

Building the System

In the ING system, much of the API interaction is driven by an API gateway. They consider their network separated into two layersOutside Network and Inside Network, with a third division of the Inside Network representing the Office network. Patrice notes the API gateways function on an external edge and an internal edge, though makes the point that there is not really an “Internal Gateway” as the design might suggest.

In terms of their API, everything, including load balancing and logical addressing, is handled primary using API service discovery. When an instance of a service is created, that service is delivered to the API Server Discovery as a an instance, group of endpoints, and an address to the client via a router. For a moment, we must take a small detour to discuss that router. At ING, they handle their router not as an external component, but as part of the client – in this way, the client code handles its own load balancing.

In the ING system, the service and endpoints are two separate things, but they are linked and controlled by something called a manifest. This manifest is essentially a well-defined, explicit link between the service and a list of API endpoints, and functions as a sort of guide for how the instance itself works.

When a software package wants to call an API endpoint, it first declares its intention to do so. At ING, this is called a subscription, which functions as a relation between the software package (also known as the application) and the specific API endpoint. When the peer-token is internally generated, the version of the API specification is stored from the moment that this subscription is created, noting the instance version as part of the greater canary system.

We’ve covered ING Bank’s API adventures in the past: From API Doing to API Thinking in a Major Bank

Utilizing the System

With all of these constituent parts in place, ING finally implements canary release through its router. The flow starts with the API and endpoints being stated in a Swagger file which exists in the API Registry. A service is attached to the API endpoints, and the manifest is then added to the service with its specific specification version. When an instance of a service is started, it gives the API Service Discovery module its physical address as a well as a manifest of all of its endpoints.

Taken from Patrice Krakow’s talk. Slide here.

When the application wants to call an endpoint, it subscribes with a list of endpoints that it can call as well as the specific version it intends to talk with. The router, either inside the code or external to it, then hands off the register peer token and information, and calls the API Service Discovery with the physical address of the endpoints. If the specific API Specification version matches, the code can be directed either to the foundational instance or to a backwards compatible version that works with that version.

In this way, the system can start offloading to a new instance that is backwards compatible with the old, and once the entire subset is tested, can dynamically increase this amount of user base. At the end, when 100% of the userbase has been transparently migrated, the old instance ids deprecated, and the new instance becomes the default in the manifest.

Conclusion: Many Industries Can Benefit From A Canary Release

Ultimately, whether or not an API provider chooses to incorporate canary release or stick to traditional versioning is entirely dependent on the specific use case of the API developer itself. While canary release does indeed make versioning much easier, it may at times be much more effort than its worth if an API only has one or two major versions every handful of years. If, however, an API is continuously shifting, constantly iterating, canary release is possibly one of the most powerful, effective methods to manage this movement.

This concept has many applications in a variety of industries. We can look at just one to see how powerful this potential concept is. The open banking movement, for example, is encouraging financial institutions to move away from older standard approaches. As such, the idea of canary release is not only a technical approach – it’s a new ethos, offering a paradigm shift in how a bank functions both in terms of financial transaction and in terms of architectural construct.

While this is a very specific application, the use of canary versioning is applicable over a wide array of functions and purposes. For that reason, it continues to be attractive to many developers. What do you think about canary release? Do you think it’s more complicated than its worth, or do you think its as promising a solution as some seem to claim it is? Let us know in the comments below.