In this article, we will learn what is Web API versioning & how to implement Web API versioning in ASP.NET Core Application. We will also explore the various options available for Web API versioning in ASP.NET Core.
Web API versioning is one of the important features to be added when developing APIs but mostly goes ignored when building a Web API application. Web API versioning in ASP.NET Core is simple and easy to implement.
Table of Contents
Introduction to Web API Versioning
When we start working on a new Web API project then at the initial stage everything works fine as we develop an initial version of the Web API with the required features. Once development is done we get it tested with all the clients and push it to production.
But the problem starts after we are in production and new changes start coming in for the existing Web API. Now There is a new change request in the existing Web API that has been released on the UAT environment for clients to update their code and test against the new Web API. All the clients have completed their development & testing but there is a delay by one of the clients to complete the changes as this new feature is not important for this client.
Now everyone has to wait for this one client to complete their work before the new version of Web API with a new change request can go live. If we push it to production then this one client will not work on the production.
Now, this is a tricky situation as this is an important change request for all the other clients & they want it to be released to production as soon as possible but if we release it then it will break the application of the client who has not completed the development & testing with the new change request.
This is where the API versioning feature can be useful. Web API versioning is a feature using which we can implement multiple versions of the same API so that different clients can work with the required version of API.
The Web API versioning allows us to implement the new version of API without impacting the existing clients on production. The Web API versioning allows us to support multiple versions of the same API i.e. old & new versions at the same time so that all existing clients can function without failing.
Following changes to Web API are considered as breaking changes in an API
- Introducing a new mandatory query string parameter – You have added a new query string parameter in the URL that is mandatory for Web API to work then in that case the old clients that do not have this query string parameter will not be able to function properly.
- Removing or renaming the endpoint – You have removed the old action and added a new action or you have renamed the old action then, in that case, the old clients that have not modified the URL path in the client code will not be able to function properly.
- Changing the data type of an existing input member – You have changed the datatype of the input parameter from string to number and are throwing an error if it’s not a number then in that case the old clients that have not modified the client code to send number instead of the string will not be able to function properly.
Implement Web API versioning in ASP.NET Core
There are various ways to implement versioning in Web API in ASP.NET Core. Here I will be covering methods to version Web API using Nuget Package Microsoft.AspNetCore.Mvc.Versioning
We can implement Web API versioning in ASP.NET Core using the following approaches
- Query String Parameter
- HTTP Header
- URL
For demonstration purposes, I have created an ASP.NET Core 3.1 Web API project. I will be using the default generated WeatherForecast Controller for implementing Web API Versioning. By default when we create the project, there is no versioning support added as shown below.
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast - Sunny Day"; } }
As shown below Install the Nuget package and enable the support for Web API versioning in the ConfigureServices method in the startup.cs file.
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddApiVersioning(apiVerConfig => { apiVerConfig.AssumeDefaultVersionWhenUnspecified = true; apiVerConfig.DefaultApiVersion = new ApiVersion(new DateTime(2020, 6, 6)); }); services.AddControllers(); } //Remaining code has been removed }
Web API Versioning using Querystring Parameter
In this approach, you need to specify the version of the API by using the ApiVersion attribute for the controller class. In this approach, if you need to define multiple versions of the same action method then you need to define the same controller/action twice in different namespaces and with different versions in the ApiVersion attribute as shown in the below code.
namespace WebAPIVersioning.Controllers.V1 { [ApiVersion("1.0")] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V1 - Sunny Day"; } } } namespace WebAPIVersioning.Controllers.V2 { [ApiVersion("2.0")] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V2 - Rainy Day"; } } }
After defining multiple versions of the same controller as shown above you can invoke these by using the version number in the query string parameter i.e. http://server:port/api/weatherforecast?api-version=1.0 or 2.0.
Below is the output screen from both versions of API
Web API Versioning using HTTP Header
In this approach, you can specify the api-version number in the header instead of the query string parameter. For this approach where the version number should be specified in the HTTP header and enable controllers to read the version number of the Api from the HTTP header, we need to configure this in the ConfigureServices method in Startup.cs file as shown below
public void ConfigureServices(IServiceCollection services) { services.AddApiVersioning(apiVerConfig => { apiVerConfig.AssumeDefaultVersionWhenUnspecified = true; apiVerConfig.DefaultApiVersion = new ApiVersion(1,0); apiVerConfig.ReportApiVersions = true; apiVerConfig.ApiVersionReader = new HeaderApiVersionReader("api-version"); }); services.AddControllers(); }
In this approach, if you need to define multiple versions of the same action method then you need to define the same controller/action twice in different namespaces and with different versions in the ApiVersion attribute as shown in the below code.
namespace WebAPIVersioning.Controllers.V1 { [ApiVersion("1.0")] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V1 - Sunny Day"; } } } namespace WebAPIVersioning.Controllers.V2 { [ApiVersion("2.0")] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V2 - Rainy Day"; } } }
After defining multiple versions of the same controller as shown in the above code you can invoke API using the version number in the HTTP header as “api-version: 1.0” or “api-version: 2.0”
Below is the output screen from both versions of the API
Web API Versioning using URL
In this approach to make the API version part of the URL, you need to define the same controller/action twice in different namespaces and with different versions in the ApiVersion attribute. Additionally, you also need to add parameter v{version:apiVersion} in the route attribute like Route("api/v{version:apiVersion}/[controller]")
as shown in the below code.
namespace WebAPIVersioning.Controllers.V1 { [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V1 - Sunny Day"; } } } namespace WebAPIVersioning.Controllers.V2 { [ApiVersion("2.0")] [Route("api/v{version:apiVersion}/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V2 - Rainy Day"; } } }
After defining multiple versions of the same controller/action as shown above you can invoke these using the version number in the HTTP URL i.e. http://server:port/api/v1/weatherforecast or http://server:port/api/v2/weatherforecast
Below is the output screen from both versions of API
Report Supported & Deprecated API Version
In the Startup.cs file while configuring API version since we have enabled parameter ReportApiVersions so any API call will return supported versions for that API in response header as shown below.
Now if you want to pass on the information that the older version of API will be removed then you can add deprecate flag to the version of API which will not be supported in future.
namespace WebAPIVersioning.Controllers.V1 { [ApiVersion("1.0",Deprecated = true)] [Route("api/[controller]")] [ApiController] public class WeatherForecastController : ControllerBase { [HttpGet] public string Get() { return "This is from WeatherForecast V1 - Sunny Day"; } } }
Summary
Web API versioning is useful when you need to enhance an existing API that is being consumed by multiple clients as by making use of Web API versioning we can support multiple versions of the same Web API. We learned about various options available in ASP.NET Core for Web API versioning.
Though there is more than one option to achieve Web API versioning in ASP.NET Core I personally prefer the URL-based versioning as that avoids extra api-version parameters in the query string and HTTP header.
Please provide your suggestions & questions in the comments section below
You can also check my other trending articles on .NET Core to learn more about developing .NET Core Applications
- Microsoft Feature Management – Feature Flags in ASP.NET Core C# – Detailed Guide
- Microservices with ASP.NET Core 3.1 – Ultimate Detailed Guide
- Entity Framework Core in ASP.NET Core 3.1 – Getting Started
- Series: ASP.NET Core Security – Ultimate Guide
- ML.NET – Machine Learning with .NET Core – Beginner’s Guide
- Real-time Web Applications with SignalR in ASP.NET Core 3.1
- Repository Pattern in ASP.NET Core with Adapter Pattern
- Creating an Async Web API with ASP.NET Core – Detailed Guide
- Build Resilient Microservices (Web API) using Polly in ASP.NET Core