Recently, there has been debate over what the best practices are for versioning an API. Many public web APIs are retired as new versions replace them, but if you were to ask Roy Fielding, creator of REST, he may tell you not to version your API at all.
Some companies are taking matters into their own hands, and seeking out innovative ways to handle the cumbersome process of keeping their Application Programming Interfaces up to date in a way that makes sense to their business model. These new strategies place more emphasis on evolution rather than deprecation.
The typical v1, v2, v3 etc. versioning approach focuses on releasing large sweeping updates to improve the API experience. But the downside of this method is that it causes a major breaking change on the client side. For internal API-first companies that have granular control over their various web, desktop, and mobile clients, continuous versioning could be a more attractive strategy.
In this article, we’ll review how public web APIs are typically versioned within our domain, and discuss why companies may want to consider a continuous versioning strategy for handling complex APIs that are subject to continual, iterative evolution. Led by Platform Summit speaker Konstantin Yakushev, we’ll use Badoo as a case study to peek into an alternative approach to versioning. Benefits like feature negotiation, and allowing for experimental development tracks could make continuous versioning strategy a win, especially for private API systems.
Typical Public API Versioning
Within most public scenarios, an API service is updated by creating an entirely new v2 and slowly deprecating the original v1. Problems with v1 are tracked — perhaps a product order is misspelled, the business logic has changed, or you want to introduce new features to your consumers. All these edits are accumulated and introduced in a v2 that solves these issues, but introduces a complete breaking change with the previous version.
An API with an endpoint such as
http//api.example.com/orders is typically reworked with a URI extension to something like
http//api.example.com/v2/orders. The v1 is then scheduled for retirement, usually in accordance with a deprecation policy. Though this is the norm, there are some significant negatives of this approach:
- Long Timeline: Instead of incremental edits, with versioning you must wait for all changes to be bundled. This means you can’t be agile in responding to specific user feedback and requests.
- Breaking: Whether you like it or not, releasing an v2 is inherently breaking the connection, and will require all clients to eventually update their connections.
- Communication: Time and resources must be spent to communicate API changes. With a v2, documentation must be updated, and deprecation timeline notices must be sent to consumers.
- Fielding as a Friend Factor: Roy Fielding defines evolvability as the ability to change over time in response to changing user needs or a changing environment without starting over. It’s actually against Roy Fielding’s own recommendation to version your API, saying it’s “only a polite way to kill deployed applications.”
Many typical versioning strategies focus too heavily on the URL construction, which to Yakushev, is “the least important step, in my opinion.” Instead, it may be better to consider the entire process from a more holistic vantage point. When we look at the API update process, we see that perhaps there is no v2 — after all, much is often salvaged, and introducing an entire new version may not be worth the effort in updating all clients.
Badoo’s Continuous Versioning Strategies
When API-first companies consistently iterate with continuous versioning, the problems listed above dissolve. To see how this actually works in practice, let’s consider some specific use cases from Badoo, the international dating network and app.
Badoo has been evolving an internal API since 2010. They’ve never had a breaking change as they’ve been incrementally updating all this time. Konstantin frankly admits that the API is not strictly RESTful, rather RPC-style and Protobuf based for mobile clients, and JSON based for their web clients.
With nearly 600 commands and over 1,200 classes, the API receives around 9 updates each week, and supports 5 types of clients (iOS, Android, Windows, Desktop Web and Mobile Web) with a healthy backwards compatibility for older client versions.
Let’s take a look into Badoo’s internal API strategy to see how they’ve used a continuous versioning mindset for specific updates to avoid major, breaking changes.
Changing the Verification Process
Yakushev describes how Badoo needed to rework their verification process. In the past, if a user signed up with their social account, they received a social checkmark associated with their account. As time grew on, the designers wanted to have more rigorous checks. For example, if a user were to verify with photo verification, they should receive a different badge.
The problem was that the original verification had a binary logic that affected other aspects of the app — the users were either verified (true) or not verified (false). Since that was the case, adding a new verification complexity meant instituting a dramatic change to their API behavior.
The Badoo team was able to solve this issue by using a GraphQL-like API to list the acceptable fields for clients. Now, when clients request the verification status, they receive more customizable options. Allowing clients to negotiate new fields is a way Badoo can update their API while keeping endpoint consistency. The old clients can use old fields, whereas the new clients use new fields.
Updating Banner CTAs for Specific Clients
However, Yakushev recognizes harder challenges in keeping their API updated and consistent across various clients. For large changes, he advises releasing new features on the server, and making clients end supported types explicitly.
For example, Badoo needs to serve various call-to-action banners for different screen sizes and device-specific interactions. If a new banner type is introduced, however, when the client asks for banners, the server could send an unknown or old banner. Typical versioning is not flexible enough here.
To solve this issue, Badoo introduced a list of supported banner types to easily decide which banners will be shown to the client. Now, client-specific banners, such as swipeable mobile-only logic can be paired with the right receiving device using the same, albeit stateful, API.
Using Flags and Feature Negotiation to Avoid Versioning
What about more complex high-level changes to business logic? Yakushev explains how all Badoo profiles have a photo feed attached to them. Over time, the design team wanted to mix in videos with the photos, and add a play button to watch the videos from within the grid view.
To resolve the issue without versioning the entire API, Badoo introduced a supported changes array. This way, the client knows that the server may send videos along with photos. A similar approach can work in many other cases — essentially you release changes behind a version flag, and make the client control these flags.
Running Experimental Features
A benefit of Badoo’s hands on approach to the entire API lifecycle is the ability to run quick experimental features on select platforms. To do this they create a superset experimental API that is only used on a select platform, such as the Windows phone, as it las low usage. Having multiple development tracks enables new features to be tested and engagement monitored.
How Continuous Versioning Could Apply to You
Depending on the situation, continuous versioning could be a powerful ally in developing and scaling agile web APIs. Instead of instigating breaking change, fields for new features are added, and the client has a list of supported items to send to the server. Yakushev recommends covering new changes with change flags, and letting the server control enabling and disabling features.
At the end of the day, client developers and product owners are happy. An iterative versioning strategy may put additional pressure on backend developers, but they may like the ability to split their work into parallel tracks for API supersets and experimental features.
In practice, Badoo has nearly 260 feature flags, and 160 negotiable features. Implementing feature negotiation at this level of complexity is more easily accomplished within an internal scenario, where communication between teams is united and both client developers and API developers are working toward similar end goal.
In Q&A discussion it was found that continuous versioning still may may not be an ideal method for public API providers. Since within continuous versioning new fields essentially equate to new features, some believe this level of feature negotiation is only acceptable when you control both the API and clients. Performing continuous versioning within a public API scenario may still need thought, nonetheless is an alluring proposition.
Have you achieved continuous versioning for your Public API? Please share your story below!