Versioning in ASP.NET Web API - 3 Different Ways

Sameer Saini March 08, 2023
Versioning in ASP.NET Web API - 3 Different Ways

ASP.NET API versioning is a technique used to version web APIs built with the ASP.NET framework.

The goal of API versioning is to allow clients to specify which version of an API they want to use and to enable developers to make changes to the API without breaking existing clients.

 

What is API Versioning?

API versioning is a technique used to manage changes to an API (Application Programming Interface) over time. An API is a set of rules and protocols that specifies how software components should interact with each other. As software evolves, changes may be necessary to the API, such as adding new functionality, modifying existing functionality, or removing deprecated functionality.

API versioning allows developers to make these changes to an API without breaking existing clients that depend on the API. It involves creating multiple versions of the API, with each version representing a specific set of functionality that is compatible with a specific client or set of clients.

 

Why is API Versioning Important?

API versioning provides developers with the flexibility and control they need to evolve and maintain an API over time while ensuring that clients can continue to use the API without interruption or additional costs.

Compatibility

API versioning allows for changes to be made to an API without breaking compatibility with existing clients. Without versioning, changes to an API would force all clients to adapt to the new API, which can be costly and time-consuming.

Flexibility

API versioning allows developers to add new features to an API or modify existing features without affecting clients that do not require the new functionality.

Dependency management

API versioning allows developers to manage dependencies between different components of a software system. By using versioned APIs, developers can ensure that each component is using the correct version of the API that it depends on.

Control

API versioning provides control over the evolution of an API. Developers can decide when and how to make changes to an API, and can provide clients with sufficient notice to adapt to the new API version.

Maintenance

API versioning can make API maintenance easier. It allows developers to focus on fixing issues and adding new features to the current version of an API, while providing a clear path for clients to upgrade to the next version when necessary.

 

How To Achieve API Versioning in ASP.NET Core

ASP.NET Core also provides support for version negotiation, which allows clients to specify their preferred API version. Developers can use the Microsoft.AspNetCore.Mvc.Versioning package to configure version negotiation options, including default version, version range, and version selection strategy.

 

URL-based versioning

URL-based versioning in ASP.NET Core involves representing different versions of an API using different URLs.

This approach is easy to implement and understand, as clients can simply request the desired version of the API by specifying the corresponding URL. Here are the steps to implement URL-based versioning in ASP.NET Core:

  1. Install the Microsoft.AspNetCore.Mvc.Versioning NuGet package in your ASP.NET Core project. You can do this using the Package Manager Console or the NuGet Package Manager in Visual Studio.

  2. In the ConfigureServices method of your Startup.cs file, configure the API versioning options by adding the following code:

    services.AddApiVersioning(options =>
    {
        options.DefaultApiVersion = new ApiVersion(1, 0);
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.ReportApiVersions = true;
        options.ApiVersionReader = new UrlSegmentApiVersionReader();
    });
    

    This code configures the default API version to be 1.0, assumes the default version when not specified in the URL, reports the API versions in the response headers, and uses the URL segment as the versioning source.

  3. In your controller, add the ApiVersion attribute to specify the supported API versions for each action method. For example:
    [ApiController]
    [Route("api/v{version:apiVersion}/[controller]")]
    [ApiVersion("1.0")]
    public class MyController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("Version 1.0");
        }
        
        [HttpGet, MapToApiVersion("2.0")]
        public IActionResult GetV2()
        {
            return Ok("Version 2.0");
        }
    }
    

    This code specifies that the controller supports version 1.0 of the API, and that the GetV2 action method supports version 2.0. The [MapToApiVersion] attribute maps the action method to version 2.0.

  4. Test the API by sending requests to the corresponding URLs. For example:

    By using URL-based versioning in ASP.NET Core, you can easily manage different versions of your API and provide backward compatibility to existing clients.

 

Query string-based versioning

Query string-based versioning in ASP.NET Core involves representing different versions of an API using a query parameter in the URL.

This approach is also easy to implement and understand, as clients can simply include the version query parameter in their requests. Here are the steps to implement query string-based versioning in ASP.NET Core:

  1. Install the Microsoft.AspNetCore.Mvc.Versioning NuGet package in your ASP.NET Core project. You can do this using the Package Manager Console or the NuGet Package Manager in Visual Studio.

  2. In the ConfigureServices method of your Startup.cs file, configure the API versioning options by adding the following code:

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

    This code configures the default API version to be 1.0, assumes the default version when not specified in the query string, reports the API versions in the response headers, and uses the "version" query parameter as the versioning source.

  3. In your controller, add the ApiVersion attribute to specify the supported API versions for each action method. For example:
    [ApiController]
    [Route("api/[controller]")]
    [ApiVersion("1.0")]
    public class MyController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("Version 1.0");
        }
        
        [HttpGet, MapToApiVersion("2.0")]
        public IActionResult GetV2()
        {
            return Ok("Version 2.0");
        }
    }
    

    This code specifies that the controller supports version 1.0 of the API, and that the GetV2 action method supports version 2.0. The [MapToApiVersion] attribute maps the action method to version 2.0.

  4. Test the API by sending requests with the "version" query parameter. For example:

    By using query string-based versioning in ASP.NET Core, you can provide a flexible and convenient way for clients to specify the desired version of your API.

 

Header-based versioning

Header-based versioning in ASP.NET Core involves representing different versions of an API using a custom header in the HTTP request.

This approach allows for versioning without affecting the URL structure or query parameters of the API. Here are the steps to implement header-based versioning in ASP.NET Core:

  1. Install the Microsoft.AspNetCore.Mvc.Versioning NuGet package in your ASP.NET Core project. You can do this using the Package Manager Console or the NuGet Package Manager in Visual Studio.

  2. In the ConfigureServices method of your Startup.cs file, configure the API versioning options by adding the following code:

    services.AddApiVersioning(options =>
    {
        options.DefaultApiVersion = new ApiVersion(1, 0);
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.ReportApiVersions = true;
        options.ApiVersionReader = new HeaderApiVersionReader("X-Version");
    });
    

    This code configures the default API version to be 1.0, assumes the default version when not specified in the header, reports the API versions in the response headers, and uses the "X-Version" header as the versioning source.

  3. In your controller, add the ApiVersion attribute to specify the supported API versions for each action method. For example:
    [ApiController]
    [Route("api/[controller]")]
    [ApiVersion("1.0")]
    public class MyController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("Version 1.0");
        }
        
        [HttpGet, MapToApiVersion("2.0")]
        public IActionResult GetV2()
        {
            return Ok("Version 2.0");
        }
    }
    

    This code specifies that the controller supports version 1.0 of the API, and that the GetV2 action method supports version 2.0. The [MapToApiVersion] attribute maps the action method to version 2.0.

  4. Test the API by sending requests with the "X-Version" header. For example:
    http://localhost:5000/api/my
    X-Version: 1.0 -> returns "Version 1.0"
    X-Version: 2.0 -> returns "Version 2.0"
    By using header-based versioning in ASP.NET Core, you can provide a flexible and non-intrusive way for clients to specify the desired version of your API.

 

Media type-based versioning

Media type-based versioning in ASP.NET Core involves representing different versions of an API using different media types in the HTTP request and response.

This approach is often referred to as "content negotiation" and is based on the Accept and Content-Type headers. Here are the steps to implement media type-based versioning in ASP.NET Core:

  1. Install the Microsoft.AspNetCore.Mvc.Versioning NuGet package in your ASP.NET Core project. You can do this using the Package Manager Console or the NuGet Package Manager in Visual Studio.

  2. In the ConfigureServices method of your Startup.cs file, configure the API versioning options by adding the following code:

    services.AddApiVersioning(options =>
    {
        options.DefaultApiVersion = new ApiVersion(1, 0);
        options.AssumeDefaultVersionWhenUnspecified = true;
        options.ReportApiVersions = true;
        options.ApiVersionReader = new MediaTypeApiVersionReader();
    });
    

    This code configures the default API version to be 1.0, assumes the default version when not specified in the media type, reports the API versions in the response headers, and uses the media type as the versioning source.

  3. In your controller, add the ApiVersion attribute to specify the supported API versions for each action method. For example:
    [ApiController]
    [Route("api/[controller]")]
    [ApiVersion("1.0")]
    [Produces("application/json;v=1.0")]
    public class MyController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return Ok("Version 1.0");
        }
        
        [HttpGet, MapToApiVersion("2.0")]
        [Produces("application/json;v=2.0")]
        public IActionResult GetV2()
        {
            return Ok("Version 2.0");
        }
    }
    

    This code specifies that the controller supports version 1.0 of the API, and that the GetV2 action method supports version 2.0. The [MapToApiVersion] attribute maps the action method to version 2.0. The [Produces] attribute specifies the media type for each version.

  4. Test the API by sending requests with the appropriate Accept header. For example:
    • http://localhost:5000/api/my
      • Accept: application/json;v=1.0 -> returns "Version 1.0"
      • Accept: application/json;v=2.0 -> returns "Version 2.0"

    By using media type-based versioning in ASP.NET Core, you can provide a flexible and powerful way for clients to specify the desired version of your API based on the content they want to receive.

Conclusion

API versioning is important because it enables software components to evolve and improve over time without disrupting existing clients. It also provides a way to manage dependencies and ensure that software components continue to function correctly as changes are made to an API.