如何在.NET 5 REST API的Swagger中同时实现API版本控制与分组功能
.NET 5 WebAPI 同时实现版本控制+Swagger分组管理完整方案
1 前置依赖安装
先安装所需NuGet包:
Swashbuckle.AspNetCore:Swagger核心组件Microsoft.AspNetCore.Mvc.Versioning:API版本控制组件Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer:版本信息暴露组件,用于对接Swagger
2 自定义扩展类
2.1 接口业务分组特性
用于标记控制器/接口所属的业务分组
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class ApiGroupAttribute : Attribute { /// <summary> /// 分组名称 /// </summary> public string GroupName { get; } public ApiGroupAttribute(string groupName) { GroupName = groupName; } }
2.2 Swagger文档过滤器
用于按「版本+业务分组」自动分配接口到对应文档
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Microsoft.AspNetCore.Mvc.ApiExplorer; public class SwaggerDocumentFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var currentDocKey = swaggerDoc.Info.Title.Split('|')[0].Trim(); // 过滤不属于当前文档的接口 var invalidApis = context.ApiDescriptions .Where(apiDesc => { var apiVersion = apiDesc.GetApiVersion().ToString(); var groupAttr = apiDesc.ActionDescriptor.EndpointMetadata .OfType<ApiGroupAttribute>() .FirstOrDefault(); var groupName = groupAttr?.GroupName ?? "Default"; var apiKey = $"v{apiVersion}_{groupName}"; return apiKey != currentDocKey; }) .ToList(); foreach (var api in invalidApis) { swaggerDoc.Paths.Remove($"/{api.RelativePath}"); } } }
3 Startup配置
3.1 ConfigureServices配置
using Microsoft.AspNetCore.Mvc; public void ConfigureServices(IServiceCollection services) { services.AddControllers(); // 配置API版本控制 services.AddApiVersioning(opt => { opt.DefaultApiVersion = new ApiVersion(1, 0); // 未指定版本时使用默认版本 opt.AssumeDefaultVersionWhenUnspecified = true; // 返回响应头中支持的版本信息 opt.ReportApiVersions = true; }) .AddApiExplorer(opt => { // 版本号格式:v1、v2 opt.GroupNameFormat = "'v'VVV"; // 自动替换路由中的版本占位符 opt.SubstituteApiVersionInUrl = true; }); // 配置Swagger services.AddSwaggerGen(opt => { // 配置所有版本+分组的文档定义,新增版本/分组只需修改下方两个数组即可 var versions = new[] { "v1", "v2" }; var groups = new[] { "User", "Order", "Payment", "Default" }; foreach (var version in versions) { foreach (var group in groups) { opt.SwaggerDoc($"{version}_{group}", new OpenApiInfo { Title = $"{version}_{group} | 接口文档", Version = version, Description = $"{version}版本 {group}业务域接口集合" }); } } // 应用自定义文档过滤器 opt.DocumentFilter<SwaggerDocumentFilter>(); // 可选:JWT授权配置,有认证需求可添加 var securityScheme = new OpenApiSecurityScheme { Name = "Authorization", Type = SecuritySchemeType.ApiKey, Scheme = "Bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "JWT授权头格式:Bearer {Token}" }; opt.AddSecurityDefinition("Bearer", securityScheme); opt.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, Array.Empty<string>() } }); }); }
3.2 Configure中间件配置
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); // 启用Swagger中间件 app.UseSwagger(); app.UseSwaggerUI(opt => { // 生成Swagger UI右上角的版本分组切换选项 var versions = new[] { "v1", "v2" }; var groups = new[] { "User", "Order", "Payment", "Default" }; foreach (var version in versions) { foreach (var group in groups) { opt.SwaggerEndpoint($"/swagger/{version}_{group}/swagger.json", $"{version} {group}接口"); } } // Swagger访问路径前缀,设为空则根路径直接访问 opt.RoutePrefix = "swagger"; }); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4 控制器使用示例
4.1 V1版本用户分组接口
[ApiController] [Route("api/v{version:apiVersion}/user")] [ApiVersion("1.0")] [ApiGroup("User")] public class UserV1Controller : ControllerBase { [HttpGet("info")] public IActionResult GetUserInfo() { return Ok(new { UserId = 1, UserName = "张三", ApiVersion = "v1" }); } }
4.2 V2版本订单分组接口
[ApiController] [Route("api/v{version:apiVersion}/order")] [ApiVersion("2.0")] [ApiGroup("Order")] public class OrderV2Controller : ControllerBase { [HttpGet("list")] public IActionResult GetOrderList() { return Ok(new { OrderIds = new[] { 1001, 1002, 1003 }, ApiVersion = "v2" }); } }
5 使用说明
- 新增版本只需在Swagger配置的
versions数组添加对应版本号即可 - 新增业务分组只需在Swagger配置的
groups数组添加对应分组名即可 - 控制器/Action未添加
[ApiGroup]特性时,默认归到Default分组 - Action上的
[ApiGroup]特性优先级高于控制器上的特性,可实现单个接口单独分组 - 启动项目后访问
/swagger即可在右上角切换不同版本、不同分组的接口文档
内容的提问来源于stack exchange,提问作者Matthew
相关产品推荐
相关产品推荐

