API Versioning in ASPNET Core

Today in this article, we will cover how to enable REST API Versioning in ASP.NET Core.

We will understand the importance of versioning and the need for the evolving API to address the new requirements along with protecting the existing API’s capability from any breaking changes.

Today we shall cover the below techniques for enabling the Versioning of ASP.NET core applications,

API Design – Contract First

As we understood in our last article Change in API is inevitable and API versioning comes to the rescue to protect your API from any breaking changes or changes in resources for any new requirements more importantly without breaking any existing clients.

The demands of the business world change daily.

Each requirement affects the Resources differently, and the resource structure is constantly evolving.

You should secure all existing clients while addressing every new requirement, and you should evolve/enhance your API to meet any new requirements with new features and resources being exposed while answering every other new requirement.

I request you to read the previous article on best practices for API Versioning and understanding Contract programming.

API versioning best practices

API Versioning

Getting started

Let’s create ASP.NET Core API using ASP.NET Core 3.1 OR .NET 6

API Versioning NET 5

Please install below NuGet package,

PM> Install-Package Microsoft.AspNetCore.Mvc.Versioning -Version <version>

Or

Install from NuGet Package Manager,

api versioning best practices

Note: Please use the latest available Nuget package supporting your .NET Core framework

Enable API Versioning in API

Please enable API versioning using the below code in the ConfigureService method in Startup.cs,

Configuration of Versioning- Generic Steps

The ApiVersioningOptions allows you to configure, customize, and extend the behaviors.

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddApiVersioning(option =>
            {
                option.DefaultApiVersion = new ApiVersion(1, 0);
                option.AssumeDefaultVersionWhenUnspecified = true;
                
            });
        }

AddApiVersioning– The configuration options are specified by providing a callback to the AddApiVersioning method.

Extension method Adds service API versioning to the specified services collection.

The ApiVersioningOptions class has the following configuration settings:

  • ApiVersionReader

  • ApiVersionSelector

  • DefaultApiVersion

  • AssumeDefaultVersionWhenUnspecified

  • ReportApiVersions

  • Conventions

  • ErrorResponses

  • RouteConstraintName

Below are brief details about these settings.

DefaultApiVersion – Gets or sets the default API version applied to the services that do not have an explicit version.

The default behavior will require clients to always specify an API version which will result in the error if the API version is not specified.

using the AssumeDefaultVersionWhenUnspecified option as true ensures the use of the default version when not specified.

The API version of the service will be selected based on the configured IApiVersionSelector.

UrlSegmentApiVersionReader – Enable Url Versioning

HeaderApiVersionReader – Enable Header Versioning

QueryStringApiVersionReader – Enable Query String Versioning

MediaTypeApiVersionReader – Enable Mediatype Versioning

Approach for Versioning on the API

before we jump on to see various Versioning techniques, let’s see how to implement the versioning at the controller or method level.

ASP.NET Core support only via explicit opt-in for the Versioning.

Versioning is supported at,

  • Controller level Versioning
  • Method level Versioning

This explicit versioning enablement is independent of any high-level options you use.

Enabling API Versioning on the API method

You assign annotation [ApiVersion] at the method level and then use any of the versioning techniques as enabled in the ConfigureServices method.

Query Versioning

It’s actually up to you to decide where you want to apply versioning depending on your preferences and requirements.

Irrespective of the location the convention of versioning works for any of the techniques.

Enabling API Versioning on Controller

You assign annotation [ApiVersion] at the Controller level and then use MapToAPiVersion at the method level indicating each HTTP method supporting a particular version.

This technique is easy and avoids confusion about the total available version on any Controller Vs used.

API Versioning

Let’s now start with Query Versioning which is the simplest and easy to configure.

API Versioning using Query string

In this type of versioning technique, you add a version number to the URI for each resource as a query string.

Existing URIs continue to operate as per contract, returning resources that conform to the original schema.

Step 1:

Please enable QueryStringApiVersionReader in ConfigureServices()

services.AddApiVersioning(option =>
            {
                option.DefaultApiVersion = new ApiVersion(1, 0);
                option.AssumeDefaultVersionWhenUnspecified = true;
                option.ApiVersionReader = new QueryStringApiVersionReader();
            });

Step2 :

We shall use the same above controller as is and execute the API as below,

[ApiController]
    [Route("api/[controller]")]
    [ApiVersion("1.0")]
    [ApiVersion("2.0")]
    [ApiVersion("3.0")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        private readonly ILogger<WeatherForecastController> _logger;
        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }
        [HttpGet]
        [MapToApiVersion("1.0")]
        public IEnumerable<WeatherForecast> GetWatherUSA()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
        [HttpGet]
        [MapToApiVersion("2.0")]
        public IEnumerable<WeatherForecastNew> GetWeatherUK()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecastNew
            {
                DateOfForcast = DateTime.Now.AddDays(index),
                Temperature = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
        [HttpGet]
        [MapToApiVersion("3.0")]
        public IEnumerable<WeatherForecastIndia> GetWeatherIndia()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecastIndia
            {
                ForcastDay = DateTime.Now.AddDays(index),
                Temperature = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }

Let’s execute the 1.0 API version,

blank

Let’s execute the API with the 2.0 version,

blank

So finally, we are able to add a version number to the query string and able to fetch the required resources.

API Versioning using URL Versioning

Using this API versioning technique client can call specific resources by specifying the version within the URL as below,

API query versioning

Please visit the below article for more details on URL API versioning techniques,

Above we can add a version number to the URL itself and able to fetch the required resources.

API Versioning Header/Media Versioning

Please visit the below article for more details on API/Media versioning techniques,

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!

References

Summary

API change isĀ inevitableĀ with constant changes in business requirements. Each requirement brings multiple changes to the Resources and their structure. API versioning could help to address new changes in resources without breaking any existing clients. Today in this article we learned a few possible approaches for versioning in the API in the ASP.NET Core ecosystem.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



Leave a Reply

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