在构建 Web API 的过程中,随着功能迭代和架构升级,接口不可避免地会发生变更。
为了确保系统的稳定性与兼容性,合理使用 API 版本控制(API Versioning) 是至关重要的。
图:ASP.NET Core API 版本控制架构概览
注意:
Microsoft.AspNetCore.Mvc.Versioning
已被弃用,推荐使用其作者维护的新库Asp.Versioning.Mvc
,它继承了原有功能并进行了增强支持,适用于 .NET 6 及更高版本。
配置 API 版本控制策略
// Configure API versioning with multiple versioning strategies
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new Asp.Versioning.ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
// Combine multiple versioning methods
options.ApiVersionReader = ApiVersionReader.Combine(
new QueryStringApiVersionReader("version"), // ?version=1.0
new UrlSegmentApiVersionReader(), // /v1.0/controller
new HeaderApiVersionReader("X-API-Version"), // X-API-Version: 1.0
new MediaTypeApiVersionReader("version") // Accept: application/json;v=1.0
);
}).AddMvc();
说明:
o UrlSegmentApiVersionReader
的优先级最高。o 支持多种方式混合使用,提高客户端调用灵活性。
Swagger 集成配置
builder.Services.AddSwaggerGen(options =>
{
// Define Swagger documents for each version
options.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "MyAPIv1",
Description = "API 文档: 版本 1"
});
options.SwaggerDoc("v2", new OpenApiInfo
{
Version = "v2",
Title = "MyAPIv2",
Description = "API 文档: 版本 2"
});
// Resolve conflicting actions by selecting the first one
options.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
// Optional: automatically group APIs by version
options.DocInclusionPredicate((version, apiDescription) =>
{
var model = apiDescription.ActionDescriptor as ControllerActionDescriptor;
return model?.ControllerTypeInfo.GetCustomAttributes(true)
.OfType<ApiVersionAttribute>()
.SelectMany(attr => attr.Versions)
.Any(v => $"v{v}" == version) ?? false;
});
});
app.UseSwaggerUI(options =>
{
// Assign endpoints for each version in Swagger UI
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPIv1");
options.SwaggerEndpoint("/swagger/v2/swagger.json", "MyAPIv2");
});
实现方式汇总
方式一:通过 URL 路径进行版本控制
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
publicclassUsersController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1.0");
}
[ApiController]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]")]
publicclassUsersV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2.0");
}
请求示例:
GET /api/v1.0/users
GET /api/v2.0/users
方式二:通过查询参数进行版本控制
[ApiController]
[ApiVersion("1.0")]
[Route("api/[controller]")]
publicclassUsersController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1.0");
}
[ApiController]
[ApiVersion("2.0")]
[Route("api/[controller]")]
publicclassUsersV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2.0");
}
请求示例:
GET /api/users?api-version=1.0
GET /api/users?api-version=2.0
方式三:通过 HTTP 请求头进行版本控制
[ApiController]
[ApiVersion("1.0")]
[Route("api/[controller]")]
publicclassUsersController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1.0");
}
[ApiController]
[ApiVersion("2.0")]
[Route("api/[controller]")]
publicclassUsersV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2.0");
}
请求示例:
GET /api/users
Headers:
X-API-Version: 1.0
方式四:通过媒体类型(Accept 头)进行版本控制
[ApiController]
[ApiVersion("1.0")]
[Route("api/[controller]")]
publicclassUsersController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 1.0");
}
[ApiController]
[ApiVersion("2.0")]
[Route("api/[controller]")]
publicclassUsersV2Controller : ControllerBase
{
[HttpGet]
public IActionResult Get() => Ok("Version 2.0");
}
请求示例:
GET /api/users
Headers:
Accept: application/json;v=1.0
各种方式对比分析
参考资料
o ASP.NET Core API 版本控制详解 o GitHub - Asp.Versioning.Mvc o Swagger 官方文档
现在就开始为你的 API 添加版本控制吧!