API Versioning In ASP.NET Core With Three Different Ways


Versioning is very important for all the web API applications which are being consumed by people for long time. For instance, our API application is being used by public for a long time and we want to make some drastic changes in the application which will affect the entire flow of the application. Obviously, the changes will affect the previous consumers also. To overcome this situation, end users also should make the changes in their application accordingly. This is not a genuine practice, right? Instead of changing the existing API application, we can create a new version of the API and give to public. It will not affect the former consumers. There are three ways to create versioning in API applications. We can see one by one.

Approach1: Versioning with URL Routes

We can pass the API version through URL routes and produce different versions of API controllers and methods.
We must install “Microsoft.AspNetCore.Mvc.Versioning” library using NuGet package manger.
We can add below entries inside the “ConfigureServices” method in Startup class.
  1. public void ConfigureServices(IServiceCollection services)  
  2.        {  
  3.            services.AddControllers();  
  4.            services.AddApiVersioning(options =>  
  5.            {  
  6.                options.ReportApiVersions = true;  
  7.                options.DefaultApiVersion = new ApiVersion(1, 0);  
  8.                options.AssumeDefaultVersionWhenUnspecified = true;  
  9.            });  
  10.        }  
We can create a new controller with default methods using scaffolding template.
I have removed all other methods except GET method. I have also added version route attribute for the controller. I have created another controller class with GET method inside the same file. Now, we have two controllers with same GET method. But it will return different results. We can check the result using Postman tool.
  1. using Microsoft.AspNetCore.Mvc;  
  2. using System.Collections.Generic;  
  4. namespace URLVersioning.Controllers  
  5. {  
  6.     [ApiVersion("1.0")]  
  7.     [Route("v{v:apiVersion}/values")]  
  8.     [ApiController]  
  9.     public class Values1Controller : ControllerBase  
  10.     {  
  11.         [HttpGet]  
  12.         public IEnumerable<string> Get()  
  13.         {  
  14.             return new string[] { "value1 - V1""value2 - V1" };  
  15.         }  
  16.     }  
  18.     [ApiVersion("2.0")]  
  19.     [Route("v{v:apiVersion}/values")]  
  20.     [ApiController]  
  21.     public class Values2Controller : ControllerBase  
  22.     {  
  23.         [HttpGet]  
  24.         public IEnumerable<string> Get()  
  25.         {  
  26.             return new string[] { "value1 - V2""value2 - V2" };  
  27.         }  
  28.     }  
  29. }  
We can enter the URL with version 1.0. This will give following result.
We can check with version 2.0 and you will get below result.
If you look at the response header, you can see the supported API versions. Currently, we have only two versions. We can add as many as we want.
In this approach, the existing consumers of the API should change endpoints to accommodate new changes. Because, we have changed the URL routes. This is a major drawback of this approach. To overcome this disadvantage, we have two more approaches available.

Approach2: Versioning with HTTP Header

In this approach, we will pass the version along with HTTP header instead of passing it as URL. We must add one more option entry for Http Header in Startup class.
  1. public void ConfigureServices(IServiceCollection services)  
  2.         {  
  3.             services.AddControllers();  
  4.             services.AddApiVersioning(options => {  
  5.                 options.ReportApiVersions = true;  
  6.                 options.DefaultApiVersion = new ApiVersion(1, 0);  
  7.                 options.AssumeDefaultVersionWhenUnspecified = true;  
  8.                 options.ApiVersionReader =  
  9.                   new HeaderApiVersionReader("X-API-Version");  
  10.             });  
  11.         }  
We have added a new Http Header entry “X-API-Version". We can modify the existing routes of controller class. We don’t need the version in route anymore.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Mvc;  
  7. namespace HttpHeaderVersioning.Controllers  
  8. {  
  9.     [ApiVersion("1.0")]  
  10.     [Route("values")]  
  11.     [ApiController]  
  12.     public class Values1Controller : ControllerBase  
  13.     {  
  14.         [HttpGet]  
  15.         public IEnumerable<string> Get()  
  16.         {  
  17.             return new string[] { "value1 - V1""value2 - V1" };  
  18.         }  
  19.     }  
  21.     [ApiVersion("2.0")]  
  22.     [Route("values")]  
  23.     [ApiController]  
  24.     public class Values2Controller : ControllerBase  
  25.     {  
  26.         [HttpGet]  
  27.         public IEnumerable<string> Get()  
  28.         {  
  29.             return new string[] { "value1 - V2""value2 - V2" };  
  30.         }  
  31.     }  
  32. }  
We can pass the version as Http Header through Postman and see the result.
If you are not passing any version as header, it will consider default version as per Startup entry and give the corresponding result. In our case, we have given 1.0 as default version.

Approach3 : Versioning with Query parameter

We can achieve the API versioning through query parameter also. For that, we must remove the previous Startup entry for Http Header.
No need to change the controller file. We can run the application and check the request in Postman using query param.
We should pass the query param as “api-version”. If you execute the request without any query param, you will get value from the controller with default version. In our case 1.0 is the default version.


In this post, we have seen three different types of versioning for ASP.NET Core Web API application. First, we have used URL routing versioning and then we have seen the versioning through Http Headers. Finally, we have seen the third option with query param. Both http header and query param methods do not affect the existing consumers of Web API. But if you choose the URL routing method, you must change all the existing endpoints of API.