Versioning is essential in API development to ensure backward compatibility and allow for incremental improvements without breaking existing clients. ASP.NET Core 8 provides robust support for API versioning through various methods. This guide covers how to implement API versioning, including URL segment versioning, query string versioning, header versioning, and best practices.
API versioning allows you to maintain multiple versions of your API simultaneously. This is critical when making breaking changes to your API while still supporting clients using older versions.
Why Use API Versioning?
ASP.NET Core provides a package specifically for API versioning. Install it using the .NET CLI.
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
dotnet add package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
Configure API versioning in the Program.cs file.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
builder.Services.AddControllers();
// Add API versioning
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionReader = new UrlSegmentApiVersionReader();
});
// Add versioned API explorer
builder.Services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
Configuration Parameters:
URL segment versioning includes the version in the URL path. This is the most commonly used versioning strategy.
4.1 Configure URL Segment VersioningEnsure the ApiVersionReader is set to UrlSegmentApiVersionReader.
options.ApiVersionReader = new UrlSegmentApiVersionReader();
Define controllers with versioned routes.
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2" });
}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2", "Product3" });
}
Explanation:
Query string versioning includes the version in the query string of the URL.
5.1 Configure Query String VersioningSet the ApiVersionReader to QueryStringApiVersionReader.
options.ApiVersionReader = new QueryStringApiVersionReader("v");
Define controllers without versioned routes. The version is determined by the query string.
[ApiVersion("1.0")]
[Route("api/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2" });
}
[ApiVersion("2.0")]
[Route("api/products")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2", "Product3" });
}
Explanation:
Header versioning includes the version in a custom HTTP header.
6.1 Configure Header VersioningSet the ApiVersionReader to HeaderApiVersionReader.
options.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
Define controllers without versioned routes. The version is determined by the custom header.
[ApiVersion("1.0")]
[Route("api/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2" });
}
[ApiVersion("2.0")]
[Route("api/products")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2", "Product3" });
}
Explanation:
You can combine different versioning methods to provide flexibility to clients.
7.1 Configure Multiple Versioning MethodsSet the ApiVersionReader to combine multiple readers.
options.ApiVersionReader = ApiVersionReader.Combine(
new UrlSegmentApiVersionReader(),
new QueryStringApiVersionReader("v"),
new HeaderApiVersionReader("x-api-version"));
Define controllers as before, ensuring they can respond to any of the specified versioning methods.
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2" });
}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2", "Product3" });
}
Explanation:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container
builder.Services.AddControllers();
// Add API versioning
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionReader = ApiVersionReader.Combine(
new UrlSegmentApiVersionReader(),
new QueryStringApiVersionReader("v"),
new HeaderApiVersionReader("x-api-version"));
});
// Add versioned API explorer
builder.Services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV1Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2" });
}
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/products")]
[ApiController]
public class ProductsV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok(new[] { "Product1", "Product2", "Product3" });
}
API versioning is crucial for maintaining backward compatibility and allowing for incremental improvements. By implementing URL segment, query string, and header versioning, you can provide flexibility to your API clients. Following best practices ensures that your API remains reliable and easy to use. This comprehensive guide provides the tools and knowledge to effectively implement API versioning in your ASP.NET Core 8 Web API projects.