.NET Zero to Hero Series is now LIVE! JOIN 🚀

8 min read

API Versioning in ASP.NET Core 3.1 - Best Practices

#dotnet

In this article, we will talk in detail about various API versioning techniques and How to implement API Versioning in ASP.NET Core 3.1 Applications. We will also go through a few of the industry’s recommended best practices. For the implementation, I will be using Visual Studio 2019 Community and ASP.NET Core 3.1 API Project Template.

What is API Versioning? (and why do you need it?)

Before deploying an API, there is a checklist of a few features that are considered vital. API versioning tops that list. It is highly crucial to anticipate changes that may be required once the API is published and a few clients are already using it. After publishing the API to a production server, we have to be careful with any future change. These changes should not break the existing Client Applications that are already using our API. It is also not a good idea to go on and change the API calls in each and every Client Application. This is how the concept of API versioning came about.

API versioning in ASP.NET Core is a technique by which different clients can get different implementations of the same Controller based on the request or the URL. So essentially, you build an API that has multiple versions that may behave differently. This is a great approach to accommodate the fact that requirements can change at any given time, and we do not have to compromise the integrity and availability of data for our already existing client applications.

Different Ways to Implement API versioning in ASP.NET Core

There are multiple ways to achieve API versioning in ASP.NET Core Applications. The commonly used approaches to version a WebAPI are as follows:

  1. Query String based.
  2. URL based.
  3. HTTP Header based.

PS, Note that, apart from these 3 approaches, there are other ways like media type, accept-header, that can be quite complex on the longer run. From the practical point of view, I believe these 3 are the go-to approaches while versioning an API. Correct me if you have a different opinion about this.

Getting Started

For this implementation, let’s create an ASP.NET Core 3.1 API Project. It will be a simple application using the auto-generated WeatherController data.

Installing the Package

Microsoft has it’s own package to facilitate the process of versioning .NET Core APIs. This Package is called Microsoft.AspNetCore.Mvc.Versioning. Let’s install it using the package manager console.

Install-Package Microsoft.AspNetCore.Mvc.Versioning

Configuring the Application to Support Versioning

Navigate to the Startup class of the API Project and modify the Configure Services method to support versioning.

public void ConfigureServices(IServiceCollection services)
{
#region Api Versioning
// Add API Versioning to the Project
services.AddApiVersioning(config =>
{
// Specify the default API Version as 1.0
config.DefaultApiVersion = new ApiVersion(1, 0);
// If the client hasn't specified the API version in the request, use the default API version number
config.AssumeDefaultVersionWhenUnspecified = true;
// Advertise the API versions supported for the particular endpoint
config.ReportApiVersions = true;
});
#endregion
services.AddControllers();
}

Folder Structure - Best Practice

Assuming that we can multiple versions of an API controller to serve different clients, I would like to have a cleaner folder-based separation of the actual controller based on the API version. In the demonstration, we have a DataController and 2 versions of the API. Here is the project folder structure for such an API.

api-versioning-in-aspnet-core-3-1

You can notice that I have separate folders based on the version of the API. Now that we have configured our application to support versioning and created the folder structure, let’s go forward to explore the 3 Best Approaches to implement API versioning in ASP.NET Core Application.

URL Based API Versioning.

Personally, this is my favorite approach and I implement this to nearly all of the APIs that I work on. It gives a clean separation between different versions. Versions are explicitly mentioned in the URL of the API endpoints. Here is how it would look like.

https://secureddata.com/api/**v1**/users
https://secureddata.com/api/**v2**/users

Implementation of URL Based API Versioning.

Here is the code for v1/DataController

namespace Versioning.WebApi.Controllers.v1
{
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class DataController : ControllerBase
{
[HttpGet]
public string Get()
{
return "data from api v1";
}
}
}

And here goes the v2/DataController.

namespace Versioning.WebApi.Controllers.v2
{
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class DataController : ControllerBase
{
[HttpGet]
public string Get()
{
return "data from api v2";
}
}
}

The most important lines are #3 and #4. Line #3 defines the API version of the controller, whereas at #4 we define the path of the versioned controller.To make it more clear, let me run the API and show you some screenshots.

api-versioning-in-aspnet-core-3-1

api-versioning-in-aspnet-core-3-1

If you notice the difference in the addresses, we have already implemented the API versioning in ASP.NET Core 3.1 Application. As easy as that. URL based versioning is more conventional. as the clients and fellow developers are able to make out the version by seeing the URL itself. It is easier for developing APIs using this approach. We will move forward to Query Based Versioning on the same application.

Query Based API Versioning.

While the previous approach has the version within the URL, this technique allows you to pass the version of the API as a parameter in the URL, ie a query string. Here is how the URL may look like.
https://secureddata.com/api/users**?api-version=1**
https://secureddata.com/api/users**?api-version=2**

Implementation of Query Based API Versioning.

There is not much of a difference from the previous implementation in terms of the code.Just change the Line #4 of each of the controllers to [Route("api/[controller]")] instead of [Route("api/v{version:apiVersion}/[controller]")]. That’s it. Let’s run the API.

api-versioning-in-aspnet-core-3-1

api-versioning-in-aspnet-core-3-1

What happens when you pass a api version that does not exist? Like, say 999?

api-versioning-in-aspnet-core-3-1

It throws an UnsupportedAPIVersion Exception saying that there is not Resource that matches API Version 999. Please see that is feature is available for any kind of versioning approach. By seeing the URLs, I guess it is self explanatory. Let’s proceed to our last approach.

HTTP Header Based API Versioning.

This approach is slightly different compared to the previous implementations and to test this, we need Postman or Swagger. I will use Postman in this demonstration to Test the Implementation. In the previous 2 techniques, we had the Version number either within the URL or passed it to the Application via a query string. Here we will pass the API version as HTTP Header in our request. This is exactly why it cannot be demonstrated using just a Browser.

Implementation of HTTP Header Based API Versioning

For this approach, we will have to modify our Startup class to support the Reading of API version from HTTP Header. Line #14 is the only addition needed to your ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
{
#region Api Versioning
// Add API Versioning to the Project
services.AddApiVersioning(config =>
{
// Specify the default API Version as 1.0
config.DefaultApiVersion = new ApiVersion(1, 0);
// If the client hasn't specified the API version in the request, use the default API version number
config.AssumeDefaultVersionWhenUnspecified = true;
// Advertise the API versions supported for the particular endpoint
config.ReportApiVersions = true;
//HTTP Header based versioning
config.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
});
#endregion
services.AddControllers();
}

Run the API and open up Postman. Paste the URL as below and add a Header Key , “x-api-version” with the required API Version. Here are the results.

api-versioning-in-aspnet-core-3-1

api-versioning-in-aspnet-core-3-1

This usage of versioning can be a bit challenging for Clients and may increase the lines of codes in the Client App.

Supporting Multiple API Versioning Schemes

Do you wonder if you could apply all these approaches to your API and let the client choose what he/she will use? Yes, Totally Possible. You can make your API support all the 3 Versioning schemes out of the box by making these simple changes.

Firstly, add the route that supports URL based routing. Make sure each of your API Controllers has the following attribute.

[Route("api/[controller]")]
[Route("api/v{version:apiVersion}/[controller]")]

Next, We will have to combine the HTTP and Query based versioning. For this go back to the ConfigService of the Startup class and modify our last line of code in the ApiVersioning extension.

config.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader(“x-api-version”), new QueryStringApiVersionReader(“api-version”));

Cheers! Now you will be able to use all the 3 API versioning Schemes seamlessly.

Deprecating an API Version

Like, adverting the supported API versions of an endpoint, the versions that are going to be removed in the near future can also be advertised on the HTTP response Header. This can be done by modifying the Route Attribute of the specific version of the API Controller.

// DEPRECATING an API Version
[ApiVersion("1.0", Deprecated = true)]

Summary

We have covered the Major 3 API versioning techniques to help build a cleaner and much scalable API in ASP.NET Core 3.1. You can find the link to the completed source code which supports all 3 API schemes in the next section. If you learned something new from this article, do not forget to share this blog post within your community to help out others as well. Leave your suggestions/experiences below in the comment section. Thanks!

Frequently Asked Questions

What are the different ways to implement versioning in a ASP.NET Core API?

The Major Schemes for API versioning in ASP.NET Core Applications are URL based, Query based and HTTP Header Request based schemes. Besides this, you have Media type and accept header schemes.

What is API Versioning?

API versioning in ASP.NET Core is a technique by which different clients can get different implementations of the same Controller based on the request or the URL. So essentially, you build an API that has multiple versions that may behave differently.

Support ❤️
If you have enjoyed my content and code, do support me by buying a couple of coffees. This will enable me to dedicate more time to research and create new content. Cheers!
Share this Article
Share this article with your network to help others!
What's your Feedback?
Do let me know your thoughts around this article.

Mukesh's .NET Newsletter 🚀

Join 5,000+ Engineers to Boost your .NET Skills. I have started a .NET Zero to Hero Series that covers everything from the basics to advanced topics to help you with your .NET Journey! You will receive 1 Awesome Email every week.

Subscribe