Crafting an Excellent Developer Experience for API Versioning

Crafting an Excellent Developer Experience for API Versioning

Versioning is a fact of life. For most APIs, there’s no avoiding it. But API versioning doesn’t have to mean broken clients. Thankfully, with proper planning and forethought, software providers can make the developer experience around versioning quite positive.

While there is no silver bullet to creating a great developer experience, some general proven strategies can help improve the API versioning process. Below, we’ll look at some techniques you can deploy to improve this experience.

Adopt Clear Communication

Versioning is, at its most basic, an avenue of communication between the developer and the user. Accordingly, adopting a policy and approach of clear communication will be a vital first step towards ensuring the developer experience is as positive and effective as possible.

Consider your communication channels, both in terms of quality and quantity. Using too many channels is just as bad as a single poor-quality channel since communication can be muddied and lost in the noise. So, keep your channels clearly delineated. For instance, some developers find that having email reserved just for critical communication is an effective approach. In general, adopting a clear and directed communication pathway will mitigate noise while reducing notification fatigue.

Also, consider the timing and historical record of this information. Letting developers know a breaking change is coming in a day or two is not effective communication, so plan your developer outreach to give ample time and notice for huge changes. Lastly, ensure there is a historical record. Keeping a log of changes will inform future users about the logic and purpose behind different version changes.

Leverage Technical Solutions

As an API provider, you have various technical solutions to ensure a smooth and efficient versioning process. Firstly, leverage HTTP standards to communicate with active users. HTTP Codes can effectively communicate with the end user about the state of the underlying resource or point to new resource locations.

Version information can also be built into the API design itself. While you can easily pass versioning as part of the URI Path Parameter, there are many methods you can employ to communicate the version and current state of the API to the end user. Matthias Biehl also suggests indicating API versioning in the Accept Header, using a custom HTTP Header, or defining API versioning as a new subdomain. All approaches still represent solid options.

Metadata is also one of the best technical tools to contextualize this information and version history. Providing ample information about your APIs, versions, and projects can help give developers vital context for the current and future versions of your service.

Have A Source of Truth

A “source of truth” is a helpful strategy to set the context for internal and external users. Using a single source of truth, as in developing against a standard specification, can help guide the development of an API and its associated microservices and serve as a boundary when it comes to versioning. This boundary can strengthen the form and function of the service and can drive development in a way that is compliant and aligned with the rest of the ecosystem.

Notably, a single source of truth brings synchronicity benefits. When you have a source you can synchronize with, you can ensure your service, documentation, developer resources, and public materials are aligned. This results in better alignment between internal services and external resources, reducing overall complexity and improving the trust developers can have in your offerings.

Make Quality Documentation

Just having a source of truth isn’t really enough, though — you have to ensure that the documentation is high quality. The documentation should be intuitively designed and as sensibly well-thought-out as your service.

Your documentation should eliminate as much surprise as possible in the life of your end developer. It should provide ample and clear context to show where your product is in its lifecycle and where it is heading in the short and long term. The documentation should provide migration guides for breaking changes, including deprecation timelines as well as reasoning for why those services are no longer useful, and so on.

Develop Intelligently

Much of the issue of versioning is not in the process itself but the reasoning behind it. The simple reality is that a significant portion of developers implement new versions when they don’t have to, introducing complexity and generating a fog of war that makes the developer’s life quite difficult.

Mitigating this issue requires some intelligent development practices. Firstly, you must be consistent and organized. APIs live and die by their utility — even the best API will ultimately fail if it’s difficult to understand or deploy. By adopting an API development pattern that clarifies and justifies both its business use case and its design ethos, your API will naturally trend toward stability rather than chaos.

Secondly, design for reusability. Reusability requires thought-out and replicable pieces and implements a self-enforced logical organization. If pieces are reusable, this institutes many policies, such as consistent naming conventions and improved discoverability, that port over to developer experience quite nicely.

Mitigate Versioning Impacts

The simple fact is that versioning will happen at some point, and in many cases, those versions may be substantial enough to negatively impact your developers. Luckily, there are some ways around the negative impacts of versioning.

First, consider a canary release strategy. This strategy allows developers to roll out new versions of a service to a small subset of users. Once this subset has grown and proven the latest version is effective and desirable, it can become the default. This approach allows for the gradual rollout of a new version. Also, it gives developers a clear opportunity to address systemic issues before they are rolled out in a dramatic fashion.

Second, consider bundling multiple breaking updates into major releases. Breaking updates are typically a poor developer experience — this is only made worse when they happen in rapid succession without a clearly communicated benefit or endpoint. Bundling these updates into one major update and communicating the how and why can shift the conversation to “adopting version 2” rather than a never-ending series of minor, annoying updates.

Consider Non-Versioning

Some options are close to “non-versioning.” While these solutions are still technically variations on versioning, they result in a developer experience that feels worlds apart.

Revisioning allows for the introduction of new functionality while ensuring legacy support for older methods. In some cases, these changes can be substantial to the business use case but can technically be very small, preventing the need for a new version altogether. This prevents “version fatigue” and breaking changes, but carries with it a development cost that can add up over time.

Other strategies, such as continuous versioning, utilize a hybrid of these strategies to allow for continual evolution without introducing breaking changes that disrupt the end developer experience.

Three Companies Doing API Versioning Right

Luckily, there are some great examples of companies doing API versioning right. Let’s quickly look at three helpful examples:

  • Stripe: Stripe provides a release system to control the version of the API you are utilizing and provides ample documentation around each change. By setting a flag in the request, you can control the version you are using. Stripe also keeps a record of backward-compatible functions, allowing developers to gain a fuller context of how each version functions.
  • GitHub: GitHub allows developers to set the version in their requests. Notably, GitHub ports new non-breaking updates to all supported API versions.
  • Microsoft Graph API: Microsoft utilizes both URI versioning and feature flags for the Graph API. More importantly, however, Microsoft has a very clear policy that new versions of the API declare the new increment as the standard, and the previous version is subject to a 24-month depreciation period. This gives ample time for developers to shift over to the new version.

Conclusion

Ultimately, with some forethought, developer experience around API versioning can be very positive and supportive. By planning your development practices and ensuring clear and consistent communication, you can ensure that your API can evolve without losing its most dedicated users — the developers who champion your product.

Did we miss any strategies to improve the developer experience around API versioning? Let us know in the comments below!