What is API Versioning? How to use it and integrate with Swagger
Most of us as Backend Developers must have had web APIs for our clients to consume or at least when we use 3rd party integrations, we must have seen the version number in the URL given us.
In an address such as “https://baseUrl/api/v1/……” you can see the version number appears as a version number for us. So to ask, what do we use these numbers for? What is the benefit of using it?
Versioning is not one of the things we consider by the time we just started a new project. However, we can give it a try if we see the future and future needs. Let’s say you have an API method you return a list of your orders. Days and weeks pass and one day you need breaking changes in your API. On the other hand, you have many clients consuming this API. What you need to do is ensure your clients won’t be affected by this change. What would you do if you were in this case? One of the options which I believe is mostly not always possible, is you talk to clients and you and your clients make your changes at the same time for all the apps. Or you can focus relatively easy method which is adding a new method into your API to serve the new model with changes. or you can do the better one. This is where API Versioning comes into our lives.
The main idea behind API Versioning, allow the same method to be called in the same way but with a different version number. In this case, Not only both old and new methods will be serving the data you want, but also your clients won’t need to make changes immediately in their system. Sounds perfect right? So how to do that?
In NET5, if you developing a WebAPI Project, just go to the startup.cs file and locate the ConfigureServices method. As a reminder, to be able to use the API Versioning feature in our project, we have to have this NuGet package to be installed. Microsoft.AspNetCore.Mvc.Versioning.
After we install the package, what we need to do is that adding this line of code into the ConfigureServices method services.AddApiVersioning();
By adding this code, we say to the NET5 that we are going to use the API Versioning feature in this project. Be prepared buddy. The second you add this code, your projects will stop working properly it is because we said we are going to use it but what we didn’t say is that how we are going to do that. Let’s configure this feature.
There are four different configs we use here. Let me explain what are they for.
The first row is important. By using this code, we say to NET5 that even my clients didn’t send any version number, please NET5 just assume that the default version is v1.0 or basically v1.
What is more important than that is the second line. It allows our clients to send no version at first, allows us to keep our methods working. We are just assuming the default version is the one I gave in the line above even though no one sends us a specific version number. Cool huh!
By adding ReportApiVersions = true into our code, we are unlocking a super cool feature. When our clients make a request to our methods, not only do we give them a response, but also give what versions they can use for this method by using Response Header.
At last but not least, ApiVersionReader allows us to specify in what ways we can get the version number from our clients. We are able to get this version number in more than one way. UrlSegmentApiVersionReader is to get the version number from the URL as I mentioned at the top of this article(v1). HeaderApiVersionReader is to get the version number from a header parameter whereas MediaTypeApiVersionReader is to get the same value from a header again but not from a new parameter instead, from the existing one, Content-Type or Accept. Usages are like that;
URL -> https://baseurl/api/v1/metod or v1.0
Header -> x-api-version:1.0
MediaType -> Accept/Content-Type: application/json; x-api-version=1.0
Once we are done having the version number we can also edit our controllers to use this feature to get the version from Route. We can specify the whole controller work only for specific versions and even we can specify the actions as well. It is not mandatory but we are able to use this in our controllers by using the ApiVersion attribute. We can also set the controller to work in more than one version like below. To get it from the Route, usage can be seen below. We now specify the controller works for v1 and also v2. The version number can be acquired from Route as well as from the other ways we configure.
When we have many methods that we want to have a different version number for them, we can use it like this.
In the OrderController, you can see in the image above, all the methods except GetOrders will accept only v1 whereas GetOrders accepts only v2 as a version. Thus, we can even specify our action methods in the same controller. However, the best practice for this scenario is to keep our actions in a different Controllers class under different directories under the Controllers folder. As an example;
In this case, the content of our controllers would be like this;
When we specify the version number as v1, the action in OrderController for v1 would work, for the v2, OrderController for v2 would work. The same URL, same client, same request but different response :-)
If we use Swagger for our clients to use, we are also able to specify the Swagger as well to work our versions and explore all the actions by classifying them by their version numbers.
Explaining the Swagger integration here would make this story way longer. I have the full project in my Github repo so you may want to give it a look. I also have a full video on my youtube channel but unfortunately, the video is in the Turkish language, but the English subtitles will be there soon.
Github Repo: https://github.com/salihcantekin/youtube_ApiVersioning
Youtube Video: https://www.youtube.com/watch?v=Iu5OnVJxCnA
Have fun. See you in the next story.