How do you implement versioning in Web APIs?
4 minintermediateASP.NET-Coreweb-apiversioning
Quick Answer
API versioning lets multiple API versions coexist so you can evolve without breaking clients, typically via the `Asp.Versioning` package. Common strategies: URL path (`/api/v1/...`), query string (`?api-version=1.0`), header, or media-type versioning. You register versioning services, mark controllers with `[ApiVersion]`, and optionally expose a version explorer for Swagger.
Detailed Answer
API versioning allows you to maintain multiple versions of your API simultaneously.
Installation:
dotnet add package Asp.Versioning.Mvc
dotnet add package Asp.Versioning.Mvc.ApiExplorer
Method 1: URL Path Versioning (Most Common)
// Program.cs
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
// Controller
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1.0");
}
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2.0 with new features");
}
// Usage:
// GET /api/v1/products
// GET /api/v2/products
Method 2: Query String Versioning
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});
[ApiController]
[Route("api/[controller]")]
[ApiVersion("1.0")]
[ApiVersion("2.0")]
public class ProductsController : ControllerBase
{
[HttpGet]
[MapToApiVersion("1.0")]
public IActionResult GetV1() => Ok("Version 1.0");
[HttpGet]
[MapToApiVersion("2.0")]
public IActionResult GetV2() => Ok("Version 2.0");
}
// Usage:
// GET /api/products?api-version=1.0
// GET /api/products?api-version=2.0
Method 3: Header Versioning
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new HeaderApiVersionReader("X-Api-Version");
});
// Usage:
// GET /api/products
// Headers: X-Api-Version: 1.0
Method 4: Media Type Versioning
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = new MediaTypeApiVersionReader();
});
// Usage:
// GET /api/products
// Headers: Accept: application/json;v=1.0
Deprecating Old Versions:
[ApiVersion("1.0", Deprecated = true)]
[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class ProductsController : ControllerBase
{
// Implementation
}
Multiple Versioning Strategies:
builder.Services.AddApiVersioning(options =>
{
options.ApiVersionReader = ApiVersionReader.Combine(
new QueryStringApiVersionReader("api-version"),
new HeaderApiVersionReader("X-Api-Version"),
new UrlSegmentApiVersionReader()
);
});