Web API Versioning in ASP.NET Core 3.1

Web API versioning though being one of the important features mostly goes ignored when building a Web API application. Web API versioning in ASP.NET Core is simple and easy to implement. In this article, we will look at what is Web API versioning along with why it is needed and how to achieve Web API versioning in ASP.NET Core.

Web API Versioning – What & Why?

Web API Versioning in ASP.NET Core

When we start a new Web API project at that time it is all fine as we develop an initial version get it tested with all the clients and push it to production. Now after going to production there are some changes in existing Web API which is a mandatory change for one of the client but it will not be possible for other clients to go live with new changes at the same time. Also, it is not recommended to change existing working clients by implementing new Web API features which they don’t need. So now if you change the existing Web API on production with breaking changes and if any of the clients don’t implement new changes it will start failing. So now there is a need to support the old version as well as the newer version of Web API so that all existing clients can function without failing.

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.

Implement Web API versioning in ASP.NET Core

There are many ways to implement versioning in Web API. Here I will be covering methods to version Web API using Nuget Package Microsoft.AspNetCore.Mvc.Versioning

We can achieve Web API versioning using following approaches

  1. Query String
  2. HTTP Header
  3. URL

Here 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 configuring Web API Versioning. By default, 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 ConfigureServices method in the startup.cs file.

Web API Versioning in ASP.NET Core 3
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

Here you need to define the same controller twice with different values for ApiVersion attribute in different namespaces as shown below.

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 using version number in querystring i.e. http://server:port/api/weatherforecast?api-version=1.0 or 2.0.

Below is the output screen from both version of API

Versioning Using Querystring

Web API Versioning using HTTP Header

For version to be part of HTTP header and enable controllers to read version number form header you need to first configure this in ConfigureServices method in startup.cs file as hows 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();
}

Then you need to define the same controller twice with different values for ApiVersion attribute in different namespaces as shown below.

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 using version number in HTTP header as “api-version: 1.0” or “api-version: 2.0”

Below is the output screen from both version of API

Versioning Using HTTP Header

Newsletter Subscription

Stay updated! Instantly get notified about my new articles in your mailbox by subscribing via email

Web API Versioning using URL

Here you need to define the same controller twice with different values for ApiVersion attribute in different namespaces as shown below. Also, you need to add parameter v{version:apiVersion} in route attribute like Route(“api/v{version:apiVersion}/[controller]”) so that API version becomes part of URL.

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 as shown above you can invoke these using version number in HTTP URL i.e. http://server:port/api/v1/weatherforecast or http://server:port/api/v2/weatherforecast

Below is the output screen from both version of API

Versioning in ASP.NET Core using HTTP URL

Supported & Deprecated API Version

In 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.

Supported API Versions

Now if you want to pass on the information that older version of API will be removed then you can add deprecate flag to the version of API which will be not 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";
        }
    }
}
deprecated API versions

Summary

API versioning is useful when you need to enhance an existing API that is being consumed by multiple clients. Versioning in ASP.NET Core Web API is easy and simple to implement. We can make use of the NuGet package Microsoft.AspNetCore.Mvc.Versioning to achieve the same.

Though there are a number of ways to achieve API versioning I personally prefer URL based versioning as that avoids extra api-version parameter in querystring and HTTP header both.

You can also check my other article on Top 12 ASP.NET Core libraries for developers: https://procodeguide.com/programming/top-12-essential-asp-net-core-libraries/

Hope you found this article useful
Buy me a coffeeBuy me a coffee

Leave a Reply

Your email address will not be published. Required fields are marked *