← Back to articles

ASP.NET Core API versioning

Part of my ASP.NET Core recipe series: adding API versioning so /api/v1/ and /api/v2/ can coexist while clients migrate at their own pace.

Tedd

With API’s often changing over time you may want to plan for versioning early on. ASP.NET Core has a library that makes versioning API a bit easier. By tagging controllers and actions with version number one can run multiple versions simultaneously.

Install

Install-Package Microsoft.AspNetCore.Mvc.Versioning

Implement

In Startup.cs ConfigureServices:

services.AddApiVersioning();

If you want to keep some URL’s without versioning, or have an existing API that is already in use then you can configure default versioning by adding:

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

Use

Versions can be in format:

  • [Version Group.].[-Status]

  • [[.Minor]][-Status]

Examples:

  • /api/foo?api-version=1.0
  • /api/foo?api-version=2.0-Alpha
  • /api/foo?api-version=2015-05-01.3.0
  • /api/v1/foo
  • /api/v2.0-Alpha/foo
  • /api/v2015-05-01.3.0/foo

Tag your controller with [ApiVersion()]. Note that you can use the tags multiple times if a controller has multiple versions. You can also make a service version neutral by tagging it with [ApiVersionNeutral].

Since we are using api area we also add version string to [Route] between api and controller name. But this would notwork with “default version” as far as I can see.

[Route("api/v{version:apiVersion}/[controller]")]
 [ApiVersion("1.0")]
 [ApiVersion("1.1")]
 [ApiController]
 public class TestController : ControllerBase
 {
... 

You can map individual methods within the controller, here using the example of “Dual”:

[Route("Dual")]
[HttpGet]
[MapToApiVersion("1.0")]
public string DualGet1()
{
 return "You got version 1.0";
}

[Route("Dual")]
[HttpGet]
[MapToApiVersion("2.0")]
public string DualGet2()
{
 return "You got version 2.0";
} 

Written by Tedd · Oslo, Norway

Updated 25 Jun 2019

Follow the journal via RSS