在 ASP.NET Core 中优雅地实现 API 版本控制

360影视 动漫周边 2025-05-18 09:22 3

摘要:⚠️ 注意:Microsoft.AspNetCore.Mvc.Versioning已被弃用,推荐使用其作者维护的新库Asp.Versioning.Mvc,它继承了原有功能并进行了增强支持,适用于 .NET 6 及更高版本。// Configure API ve

在构建 Web API 的过程中,随着功能迭代和架构升级,接口不可避免地会发生变更。

为了确保系统的稳定性与兼容性,合理使用 API 版本控制(API Versioning)是至关重要的。

图:ASP.NET Core API 版本控制架构概览

⚠️ 注意:Microsoft.AspNetCore.Mvc.Versioning已被弃用,推荐使用其作者维护的新库Asp.Versioning.Mvc,它继承了原有功能并进行了增强支持,适用于 .NET 6 及更高版本。// 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;

📌 说明:

UrlSegmentApiVersionReader的优先级最高。

• 支持多种方式混合使用,提高客户端调用灵活性。

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
.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")]

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")]

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 请求头进行版本控制

请求示例:

GET /api/users
Headers:
X-API-Version: 1.0📍 方式四:通过媒体类型(Accept 头)进行版本控制

请求示例:

GET /api/users
Headers:
Accept: application/json;v=1.0

方式

优点

缺点

URL 路径

清晰直观,易于调试

不易迁移旧路径

查询参数

简单易用,对客户端透明

不够语义化

请求头

对客户端无侵入性

需要客户端配合设置 header

MediaType

符合 RESTful 设计规范

实现复杂,需处理 content negotiation

现在就开始为你的 API 添加版本控制吧!🚀

来源:opendotnet

相关推荐