Swagger UI .NET Core 中的 API 版本控制和启用授权
一、API 版本管理的概述
API 版本管理是一种技术,通过它可以创建多个版本的 API 并使其同时共存。这种技术不仅可以保持与旧客户端的向后兼容性,还能为新客户端提供新特性和改进。随着应用的演变,可能需要引入对 API 的重大变更。API 版本管理有助于以不影响依赖于旧版本 API 的现有用户的方式来管理这些变更。
二、API 版本管理的实现方式
在 .NET Core Web API 中,有几种常见的 API 版本管理实现方式:
1. URL 版本管理
这种方法是最常见的实现方式,版本号作为路径的一部分。例如:
/api/v1/purchaseOrders
2. 查询字符串版本管理
这种方法通过查询参数传递版本,保持相同的 URL 路径,并用额外的查询参数指示版本。例如:
/api/purchaseOrders?api-version=1.0
3. 头部版本管理
在这种方法中,版本通过自定义请求头传递,版本包含在请求头中,而不是 URL 中。例如:
GET /api/purchaseOrders
HTTP
Headers: x-api-version: 1.0
4. 媒体类型版本管理(接受头版本管理)
通过内容协商传递版本,版本包含在 Accept 头中,以自定义媒体类型的形式请求特定版本的 API。例如:
GET /api/purchaseOrder
HTTP
Headers: Accept: application/vnd.companyname.v1+json
三、实现 API 版本管理的步骤
1. 创建 Web API 项目
创建一个 .NET Core Web API 项目,并命名为 "APIVersioingPOC"。
2. 添加必要的 NuGet 包
使用 NuGet 包管理器添加以下必需的包:
Install-Package Asp.Versioning.Mvc
Install-Package Asp.Versioning.Mvc.ApiExplorer
3. 创建实体类
在项目中创建一个名为 "Entity" 的文件夹,并添加名为 "PurchaseDetails" 的实体类。
namespace APIVersioingPOC.Entity
{
    public class PurchaseDetails
    {
        public string ProductName { get; set; } // 产品名称
        public int Rate { get; set; } // 价格
        public int Qty { get; set; } // 数量
        public int Amount { get; set; } // 总金额
    }
}
4. 创建服务类
在项目中创建一个名为 "Service" 的文件夹,并添加接口 "IPurchaseOrderService" 和服务类 "PurchaseOrderService"。
using APIVersioingPOC.Entity;
namespace APIVersioingPOC.Service
{
    public interface IPurchaseOrderService
    {
        List<PurchaseDetails> GetPurchaseOrders(); // 获取购买订单列表的方法
    }
}
using APIVersioingPOC.Entity;
namespace APIVersioingPOC.Service
{
    public class PurchaseOrderService : IPurchaseOrderService
    {
        public List<PurchaseDetails> GetPurchaseOrders() // 实现获取购买订单的方法
        {
            return new List<PurchaseDetails>
            {
               new PurchaseDetails { ProductName = "Laptop", Rate = 80000, Qty = 2, Amount = 160000 }, // 笔记本
               new PurchaseDetails { ProductName = "Desktop", Rate = 40000, Qty = 1, Amount = 40000 }, // 台式机
               new PurchaseDetails { ProductName = "Hard Disk", Rate = 4000, Qty = 10, Amount = 40000 }, // 硬盘
               new PurchaseDetails { ProductName = "Pen Drive", Rate = 600, Qty = 10, Amount = 6000 } // U 盘
            };
        }
    }
}
5. 注册服务
在 Program.cs 文件中注册服务。
// 添加自定义服务
builder.Services.AddScoped<IPurchaseOrderService, PurchaseOrderService>(); // 注册购买订单服务
6. 配置版本管理
在 Program.cs 文件中添加以下代码以配置版本管理。
var builder = WebApplication.CreateBuilder(args);
// 添加 API Explorer,以提供可用版本的信息
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0); // 默认 API 版本(v1.0)
    options.AssumeDefaultVersionWhenUnspecified = true; // 未指定时假设默认版本
    options.ReportApiVersions = true; // 在响应头中报告 API 版本
    options.ApiVersionReader = new UrlSegmentApiVersionReader(); // 使用 URL 段版本(例如,/api/v1/resource)
}).AddApiExplorer(options =>
{
    options.GroupNameFormat = "'v'VVV"; // 版本分组格式
    options.SubstituteApiVersionInUrl = true; // 在 URL 中替换 API 版本
});
builder.Services.AddSwaggerGen(); // 添加 Swagger 生成器
var app = builder.Build();
app.UseSwagger(); // 启用 Swagger
app.UseSwaggerUI(options =>
{
    var provider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>(); // 获取版本描述提供程序
    foreach (var description in provider.ApiVersionDescriptions)
    {
        options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant()); // 为每个版本配置 Swagger 端点
    }
});
7. 配置 Swagger 选项
在项目中创建一个名为 "OpenApi" 的文件夹,并添加 ConfigureSwaggerOptions 类以配置 Swagger 选项。
using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace APIVersioingPOC.OpenApi
{
    public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
    {
        private readonly IApiVersionDescriptionProvider _provider; // 版本描述提供程序
        public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
        {
            _provider = provider; // 构造函数注入
        }
        public void Configure(SwaggerGenOptions options)
        {
            foreach (var description in _provider.ApiVersionDescriptions) // 遍历每个版本描述
            {
                options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description)); // 创建 Swagger 文档
            }
            // 添加令牌认证选项以传递 Bearer 令牌
            options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                In = ParameterLocation.Header, // 定义位置为头部
                Description = "请输入令牌", // 描述
                Name = "Authorization", // 头部名称
                Type = SecuritySchemeType.Http, // 类型为 HTTP
                BearerFormat = "JWT", // Bearer 格式
                Scheme = "bearer" // 方案
            });
            // 添加安全方案
            options.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme, // 类型为安全方案
                            Id = "Bearer" // 引用 ID
                        }
                    },
                    new string[] { } // 允许的范围
                }
            });
        }
        private static OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription apiVersionDescription) // 创建版本信息
        {
            var info = new OpenApiInfo
            {
                Title = "API 版本管理", // 标题
                Version = apiVersionDescription.ApiVersion.ToString(), // 版本号
                Description = "API 版本管理的 Swagger 文档。" // 描述
            };
            // 添加已弃用 API 描述
            if (apiVersionDescription.IsDeprecated)
            {
                info.Description += " 此 API 版本已被弃用。"; // 说明
            }
            return info; // 返回信息
        }
    }
}
8. 注册 Swagger 配置
将以下代码添加到 Program.cs 中以注册自定义 Swagger 配置服务。
// 添加自定义服务
builder.Services.AddSingleton<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(); // 注册 Swagger 配置
9. 创建控制器
创建名为 PurchaseOrderController 的控制器。为演示目的,创建两个版本的相同 API 端点。
using APIVersioingPOC.Service;
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace APIVersioingPOC.Controllers
{
    [ApiController]
    [Route("api/v{version:apiVersion}/[controller]")] // 设置路由以包含版本号
    [ApiVersion("1.0")] // 声明版本 1.0
    [ApiVersion("2.0")] // 声明版本 2.0
    [Authorize] // 需要授权
    public class PurchaseOrderController : ControllerBase
    {
        private readonly IPurchaseOrderService _
purchaseOrderService; // 购买订单服务
        public PurchaseOrderController(IPurchaseOrderService purchaseOrderService) // 构造函数注入
        {
            _purchaseOrderService = purchaseOrderService; // 初始化服务
        }
        [HttpGet("GetPurchaseOrders")] // HTTP GET 请求
        [MapToApiVersion("1.0")] // 映射到版本 1.0
        public IActionResult GetPurchaseOrders() // 获取购买订单的方法
        {
            var users = _purchaseOrderService.GetPurchaseOrders(); // 调用服务方法
            return Ok(users); // 返回结果
        }
        [HttpGet("GetPurchaseOrders")] // HTTP GET 请求
        [MapToApiVersion("2.0")] // 映射到版本 2.0
        public IActionResult GetPurchaseOrdersV2() // 获取购买订单的 V2 方法
        {
            var purchaseDetails = _purchaseOrderService.GetPurchaseOrders(); // 调用服务方法
            return Ok(purchaseDetails); // 返回结果
        }
    }
}
四、运行项目
启动项目后,对于默认版本 V1,您将看到如下的 Swagger 文档:
Swagger 文档

对于版本 V2,从“选择定义”下拉框中选择 V2 选项,您将看到如下的 Swagger 文档:
选择定义

您可以传递认证令牌,并点击授权按钮进行授权:
授权按钮

五、总结
通过上述步骤,我们学习了如何在 .NET Core 8 中实现 API 版本管理,并在 Swagger UI 中启用授权。这种方式可以确保新旧版本的 API 同时存在,满足不同客户端的需求。希望这篇文章能够帮助开发者更好地理解和实现 API 版本管理。