Best Practices For Your API Versioning Strategy

Best Practices For Your API Versioning Strategy

API versioning is critical. But do you know all of the API versioning best practices? Is your API versioning strategy sound??

What Is API Versioning?

API versioning?is the process of iterating different versions of your API. Ultimately a part of?API design, API versioning often accommodates API consumption changes, structural API shifts, and modifications to the underlying software or program which the API has been built upon.

Versioning APIs is one of the?API basics?you need to know. When your?APIs?outgrow their original scope, you'll need to modify them to adapt to changing requirements. Obviously, API versioning isn’t something that happens at random. Unlike server maintenance, it won’t happen at regular intervals either.

If you are creating a new version of your API, you are likely seeing a big shift in consumption, or changing the functionality of the software your API is built upon. Yet, smaller bug fixes might not require versioning seeing as the general goal is to keep an API version as stable as possible, while?avoiding any breaking changes for consumers.

Why Is API Versioning Required?

API versioning is required because it ensures stability and reliability. If you don't properly version APIs,?it?can have disastrous effects on downstream products and services.

Like any other technology, APIs are interconnected and rely upon various systems, software, and databases to function. As the technology landscape continues to drastically shift, APIs must adapt their?requirements,?documentation, consumption protocols, and structure in order to keep up.

It is only in rare circumstances that an API will not require versioning. Most APIs outgrow their original scope, or require bug fixes. Although, a well-planned API could reliably function without intervention for many years, if the planning team had accurately forecast all competing variables.

5 API Versioning Best Practices

Here are four API versioning best practices you need to know:

  1. Enable backwards compatibility.
  2. Refresh?API documentation?to reflect new versions.
  3. Adapt API versioning to business requirements.
  4. Put?API security?considerations at the forefront.
  5. Set your API versions up to scale.

How to Build an API Versioning Strategy?

You will likely need to build an API versioning strategy that can support multiple API versions.

If you haven’t run into this issue in your?API strategy, you will. As your?API management?efforts grow, the complexity of your footprint will likewise escalate. Creating new versions of an API will not guarantee your API consumers will adopt these new versions right away, if at all. Which means you will need to accommodate backwards compatibility or support multiple versions of an API running in parallel.

There are two recommended API versioning strategies to resolving this issue.

1. Versioning Through URI Path

Your universal resource identifier (URI) acts as the parent path for your URL. Or more simply, if your URL were a page in a book, your URI is the book itself. URI path versioning is Akana’s preferred method, and the industry gold standard. This approach is common among many of the leading technology players who have built their businesses around APIs. We’re talking Facebook, Airbnb, Twitter, the whole lot of them.

How to Do URI Versioning For APIs

If you are making a breaking change to your API, meaning any change that could break a client’s application, it is important that your API consumers know the change is being made. This patch is typically reserved for bug fixes. Here are two common scenarios.

Major or Minor Patch

There are different ways to communicate to API consumers whether you are making a major or minor patch.

  • Major patch:?In this approach, your URI would denote the breaking changes to the API. A new major version requires creating a new API. The version number is what you use to route to the correct host via your URI.
  • Minor patch:?You update change logs to inform API consumers of new functionality or bug fixes. Or, you could correlate minor to a lifecycle coordinator iteration, in which that minor introduces a non-breaking functionality.
  • Patch versions:?These are made open and available to the client and used internally for API backwards-compatibility. These are also commonly communicated via change logs.

So what if you have multiple versions of an API running? In this case, leave your first version running and put a deprecation timeline in place for clients to move to version two. The deprecation timeline could, in theory, be infinite. If the change is non-breaking, simply iterate V1 API in the platform and underlying implementation. If you wish, you could use lifecycle coordinator to track iteration history of specific APIs.

2. API Versioning Through Content Negotiation

The second option for API versioning is to use content negotiation. This approach versions resources based on their representational state, or media type. We typically do not recommend this, but some organizations have success with this approach. If you are utilizing content negotiation to version your APIs, consider a few of the following points:

Strongly Typed Interfaces Will Not Be Possible

Strongly typed interfaces will not be possible, from the?API platform?and visibility enforcement standpoint. Which means, it will be difficult to trust the client app to match with the underlying implementation selected by content header version.

Virtual Service (API Proxy) Utilization

You will need to utilize a virtual service (API proxy) in order to allow multiple versions and implementations to funnel through.

The above process will prevent managing and contracting each API version separately. You will have no idea which apps are using which versions of your API, and whether it is safe to retire old versions.

Accessibility

This approach is also less accessible than URI-versioned APIs. When you require HTTP headers with media types, it is more difficult to explore the API using a browser.

Overall, content negotiation is a more granular approach. It versions resource representations instead of versioning the entire API. Likewise, it comes with a high implementation cost for clients and developers. More often than not, content negotiation needs to be implemented from scratch because there are few API libraries that offer it out of the box.?

API Versioning Do’s and Don’ts

It’s never too soon to get started crafting your versioning strategy


Often when developing our APIs, we tend to ignore versioning because we’re literally building the first-ever version of our service. We can worry about versioning in the future, right?

Wrong.

Four months down the road we realize we need a new version of our API and suddenly a million questions pop up in our mind about the user experience, the breaking changes, the time to update and we realize just then that by ignoring the problem, in the beginning, we had just shoot ourselves in the foot, we just didn’t know it yet.

So let’s take a look at some bad and good practices when it comes to thinking and planning around the versioning strategy for your next API, so you can keep the other foot from being shot.

Versioning strategy

The whole idea of this article is that you need to have a way to organize the way you version your API. The better laid out your strategy is, the faster you’ll be able to grow and extend your API without affecting your users.


What is a versioning strategy? Essentially is a set of standards that you’ll use whenever you want to specify a new version of your API. Standards, by definition, are well documented, always follow a set of logical rules and if there are exceptions, they are clearly documented as well. The standard might include things like:

  • The logic behind the numbering system you’re using. Because after all the version number is supposed to mean something, otherwise what’s the point of using it?
  • The release schedule if there is one.
  • How to deal with multiple versions and what happens during a big update.
  • Default versions to use, deprecated versions to stop using, etc.

Really, the more you add the better it’ll be for your users.

So a big no-no would be to version your API however you see fit.

In practice, this means you’re:


  1. Arbitrarily choosing version numbers depending on how you feel that day. This is per se not a terrible thing, however, it does make it a lot harder for users to understand which version they’d like to use solely based on the number.
  2. You may not even be thinking about how the breaking changes you’re introducing will affect active users of your API. This is major and can hinder API adoption greatly because it essentially renders it unstable in the eyes of the client.
  3. You do not have a release schedule/way for your users to understand if improvements are coming soon. This renders the API obsolete the moment they see the need for improvements but can’t really tell if they’re coming or not.

What can you do to avoid all these problems and perceptions issues (because after all you might be working on the best API in the world and no one would realize that given the current lack of versioning strategy)?

Have a solid, well defined, and documented strategy

I don’t think that given the previous point, this will be a shocker. But just to make sure the point gets across: define a versioning strategy, publish it somewhere and make sure you stick to it.


What am I talking about here? Things like:

  • Defining what versioning scheme you’re using. This will give a hint to your users about what each new version implies. For example you can go with?SemVer?which would let your users know that if you go from 1.2 to 1.3 you’re just adding some non-breaking improvements, but if you go from 1.2 to 2.0, then something is probably going to break. Or you can follow Ubuntu’s versioning scheme which indicates the date of the release, so 21.01 would mean you released that version on January 2021. You’re adding value to your users by telling them exactly how old that version is. It doesn’t really matter what scheme you use, as long as you use one and document it clearly.
  • Letting your users know what happens to old versions after every new release. Are they deprecated? No longer accessible? Maybe kept accessible for a while? I personally have my own preference and I’ll share it with you down below, but consider being open about this and having it clearly documented somewhere.
  • Giving your users a high-level roadmap of what’s coming. It doesn’t have to be a fixed timetable where you commit to a specific number of improvements by a date. Just let them know what your plans are, by what version you might release each new feature and keep it updated. That way they’ll know you’re working on something new and they’ll know when to, roughly, expect it.

The point of the strategy is to give users and client app developers a standard way of knowing how to interact with your API and its different versions. Effectively stabilizing the development in the eyes of your users.

One version to rule them all

Versioning is fun until you have to decide what to do with older versions when a new one comes along.


Of course, this is only important if you actually have someone using your older versions, but let’s assume that’s the case here.

A big no-no in my book: only keep the latest version available online

Do you really hate your users that much?


Only having a single version available might seem like a good idea, because your clients will always have the latest version and every bug fix and new feature will automatically be available to them. Amazing!

Not so much.

Because the other thing that you can do when updating the API is releasing breaking changes. That’s completely valid, sometimes to move forward you have to break some egg you know? — that’s how the saying goes, isn’t it? — . The point here is that a new release might be as terrible as having a lot of crashing bugs. In the eyes of your clients, you’re releasing a very unstable product.

That’s not what we want.

Keep multiple versions in parallel

What can you do instead? With a well-defined versioning strategy, when releasing a non-backwards compatible version, you can keep the existing one and the new one working in parallel for a pre-defined window of time.


While that happens, you can notify your clients about the changes, and the deadline for them to update, if they so wish to do, before you’ll deprecate the older version.

And on top of that, if you’re following a versioning scheme like SemVer, you can automatically deploy minor and patch updates, without fearing issues with your client, and only leave major changes to be released through this process. That way clients only need to worry about specifying the major version of your API , instead of the full one (i.e they can say that want to use version 1 instead of 1.2.5 or 1.5.2).

Mind you, you don’t have to keep every single major version online forever, if you’re not releasing major versions every week, as long as you keep the last 2 versions online (i.e the new one and the previous one) it’ll be enough. Between then and the next major release, you need to make sure that you have very few users using the old — soon to be deprecated — version.

Documentation is for suckers

The documentation of an API will determine how much adoption it’ll get from its users. The better it is, the simple it’ll be for them to use it, you’re lowering the learning curve, and that’s something every user loves.


Big don’t: Assuming you don’t need to document obvious behavior

So a big no-no when it comes to versioning is assuming it’s obvious to everyone, and either you barely mention it in your documentation, or you avoid it completely.


Do not leave anything to the imagination of your users, for any aspect of your product, but especially not for one that dictates how they interact with it.

If given the choice, they might think it’ll be safer to lock their client into a specific version and forget about it. However, what happens if you decide to deprecate that version?

Or perhaps they think “new version” means “better version” — I mean, who wouldn’t? — so they keep always using the latest version. When are you going to tell them you’re breaking half of their client with your latest update?

Do: clearly document your strategy around versioning

The best practice here would be to have a dedicated section of your documentation where you clearly outline the versioning scheme used, what happens after each new release and cover how each type of release affects the existing clients. That last part is crucial because you want your users to clearly understand how they’ll be affected by a new version.


A fantastic practice would also include a release log after every new version bump. Even if it’s just a minor release, it should be a big deal for you — which in turn shows your users you care about them — and it should have a dedicated section within the release history.

Check out Shopify’s release docs as an example:

No alt text provided for this image

You can see several things in that screenshot:

  1. They follow a time-based versioning scheme.
  2. They Document every new version’s release individually and in detail.
  3. They even have a “developer previews” version, which is probably updated often with the latest new changes.

If you click on any of them, you’ll notice the level of detail, showing you things like:

  • Release date, so you know how exactly how old this version is.
  • The deprecation date, or how they put it: the date when this version is no longer going to be supported. This is major, as a client of this version, you now know exactly when you can no longer use it.
  • What’s new? The list of updates.
  • Breaking changes. Yes, they have a dedicated version for everything that will break your client application if you switch to this new version. That is what I call a user-centric approach.

Think about your users, not about how much documentation you need to write. I’ll leave it at that.

Standandars, schmandars

Who needs standards when you can define your own way of specifying things like what version your client wants to interact with, right?


If you’re keeping multiple versions of your API alive at any given point, you’ll have to provide your users with a way of telling you that, and the way you do so will also tell a lot about how much you care — or don’t care — about them.

Big don’t: come up with a very unique way of doing it

Perhaps you think that this whole versioning thing is not really a standard within your communication protocol so you’ve decided to come up with a unique way of specifying the version of your API.


Or maybe, you just didn’t take the time to research your actual communication protocol to find out how many different, standard, ways of doing it are there.

Whatever the case may be, forcing your clients to follow your non-standard ways will make their libraries obsolete. Remember, they’re most likely using libraries that deal with your communication protocol so they don’t have to re-invent the wheel. However, those libraries will usually (like 99% of the time) assume both client and server will follow the standards for the channel.

So if you’re using HTTP — which, let’s face it, it’s probably the channel 99,9% of you are using — for example, the library you’ll use won’t take into account things outside either the headers, the URL or the query parameters, to specify the version.

If you think you have a nifty new idea, consider the effect it’ll have on your clients. In fact, what about your API’s adoption rates? The harder you make it for your users, the fewer of them will actually want to use your service.

Make it easy for them to tell you the version they want to use

It’s that simple.


The easier you make it, the happier your clients will be. And you want them to be happy, remember that.

What options are there? Again, sticking to HTTP which is the channel I’m assuming you’re using here:

  • Header as part of the request.?But not?any?header, HTTP has a thing called content negotiation which allows you to specify the type of representation that your client accepts of the resource requested. So through?the?Accept?header, you can specify things like the mime type of the response as well as the version of it. That way you can have the same set of endpoints but through this header you specify the version of it. If you’re building a truly RESTful API, this is probably the best way to tackle versioning. The drawback of this approach, is that you either need to have a reverse proxy or some kind of gateway redirecting the request to the correct instance of your API based on this header, or you have to have that redirect logic inside your own API (essentially having all versions of the service living within the same product).
  • The version inside the URL.?This implies having URLs such as?/api/v1/your-endpoint-here?. So if you now want to move on to version 2, just change it to?/api/v2/your-endpoint-here?. That’s a valid option, many use it. The problem with it? You’re technically coupling the unique resource identifier (i.e the ID of the resource you want to interact with) with the representation of the resource. For instance, consider the following request:?GET /api/v1/images/family-photo.jpg?and now?GET /api/v2/images/family-photo.jpg?. To HTTP, and thus at least to a truly RESTful API, those are two completely different resources, however, in practice, they’re most likely the same picture. It’s just a matter of you having updated the version of the API and now changing their ID. By definition the URI/URL of a resource should never change over time, so you’re breaking a standard. Mind you, if you’re not going for REST this might not be a problem for you, but keep it in the back of your head, just in case.
  • Specify the version as part of the query parameters.?If you want to keep the version in the URL but avoid the above problem, try to shift it into the query params instead. So instead of doing?/api/v1/images/family-photo.jpg?you can say?/api/images/family-photo.jpg?v=1?. You’re now using the params (which are not part of the unique ID) to do content negotiation. If you don’t have that many parameters at any given time, this might be a great solution. However, if you’re already using lots of them on all your endpoints, this will only add more noise to the full URL. This one has the same drawback as the first option: you need to figure out how to route the request to the right version. It’s not a big drawback, since there are multiple ways of doing so, but it’s still something you need to think about.

Those are the 3 most common ways of specifying the version of an API in the request. If you think you need something different, think again. Your users will thank you.

There you go, API versioning is no joke, you need to pay as much attention to it as you do to any other aspect of its development. And as such, you should consider having a strategy for it from the start. Even if you’re not considering having a new version of it for the next year, starting with a set plan will help you plan everything else around it instead of making it up as you go.

Finally, think about your users and about your API adoption when defining the versioning strategy, it’ll directly affect them — and in a bad way if you don’t do it properly.

Enjoyable article

回复

要查看或添加评论,请登录

Omar Ismail的更多文章

  • OAuth Grant Types (Authorization Code Grant)

    OAuth Grant Types (Authorization Code Grant)

    The authorization code grant type is used to obtain both access tokens and refresh tokens. The grant type uses the…

  • What is Apache Kafka?

    What is Apache Kafka?

    Reference : https://www.qlik.

    2 条评论
  • Multi-Tenant Architecture in a Nutshell

    Multi-Tenant Architecture in a Nutshell

    Thanks to the original writer and article :…

  • Microservices Communication!

    Microservices Communication!

    Thanks To: https://medium.com/design-microservices-architecture-with-patterns/microservices-communications-f319f8d76b71…

    2 条评论
  • What Are the New Features of SpringBoot3 ?

    What Are the New Features of SpringBoot3 ?

    Thanks to : https://medium.com/javarevisited/what-are-the-new-features-of-springboot3-6ddba9af664 1.

    1 条评论
  • OAuth 2.0!

    OAuth 2.0!

    Thanks to the original writer : https://medium.com/@isharaaruna OAuth2.

    2 条评论
  • How to Draw a Technical Architecture Diagram

    How to Draw a Technical Architecture Diagram

    Thanks to the original writer and article : https://levelup.gitconnected.

    2 条评论
  • Event Sourcing Versus Event-Driven Architecture

    Event Sourcing Versus Event-Driven Architecture

    Thanks to the original writer and article :…

  • Enterprise Architecture Tools

    Enterprise Architecture Tools

    Thanks to the original writer and article : https://medium.com/geekculture/enterprise-architecture-tools-b8165c8c9d7…

  • Solution Architecture: Foundations

    Solution Architecture: Foundations

    Thanks to the original article : https://medium.com/@yam-yam-architect/solution-architecture-foundations-fb4af948bb02…

社区洞察

其他会员也浏览了