ASP.NET Core – Swagger API Versioning

前言

Versioning 会导致 Swagger 直接坏掉. 因为 1 个文档无法支持多个版本. 所以需要每一个版本做一个文档.

 

主要参考

Integrating ASP.NET Core Api Versions with Swagger UI

What every ASP.NET Core Web API project needs - Part 2 - API versioning and Swagger

Docs – aspnet-api-versioning(最新版本,上面的是旧版本的参考)

Stack Overflow – iServiceCollection' does not contain a definition for 'addVersionedApiExplorer'

 

安装 Versioning.ApiExplorer

dotnet add package Asp.Versioning.Mvc.ApiExplorer

 

Program.cs

var apiVersioningBuilder = builder.Services.AddApiVersioning(options =>
{
  options.AssumeDefaultVersionWhenUnspecified = true;
  options.DefaultApiVersion = new ApiVersion(1, 0);
  options.ReportApiVersions = true;
}).AddMvc();

apiVersioningBuilder.AddApiExplorer(options =>
{
  options.GroupNameFormat = "'v'VVV";
  options.SubstituteApiVersionInUrl = true;
});

AddApiVersioning 后会返回一个 versioning builder,利用它来继续 setup Swagger 的部分。

做一个 ConfigureSwaggerOptions.cs

之前的 XML, OpenApiInfo 放进去, 关键就是让它变成动态创建, 依赖 version.

using System.Reflection;
using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace WebApi;

public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) : IConfigureNamedOptions<SwaggerGenOptions>
{
  private readonly IApiVersionDescriptionProvider provider = provider;

  public void Configure(SwaggerGenOptions options)
  {
    foreach (var description in provider.ApiVersionDescriptions)
    {
      options.SwaggerDoc(description.GroupName, CreateVersionInfo(description));

      var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
      var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
      options.IncludeXmlComments(xmlPath);
    }
  }

  public void Configure(string? name, SwaggerGenOptions options)
  {
    Configure(options);
  }

  private static OpenApiInfo CreateVersionInfo(ApiVersionDescription description)
  {
    var version = description.ApiVersion.ToString();
    var info = new OpenApiInfo()
    {
      Title = "Project Web API",
      Version = $"v{version}",
      Description = $"DB&Project Web API version {version}",
      Contact = new OpenApiContact
      {
        Name = "Derrick Yam",
        Email = "hengkeat87@gmail.com",
      },
    };
    if (description.IsDeprecated)
    {
      info.Description += " This API version has been deprecated.";
    }
    return info;
  }
}

配置

builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();

最后是 UI, 需要注入 IApiVersionDescriptionProvider

app.UseSwaggerUI(options =>
{
    foreach (var description in app.Services.GetRequiredService<IApiVersionDescriptionProvider>().ApiVersionDescriptions)
    {
        options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", $"Project Web API v{description.ApiVersion}");
        options.DocExpansion(DocExpansion.None);
    }
});

这样就可以了

 

posted @ 2021-10-25 20:22  兴杰  阅读(293)  评论(0编辑  收藏  举报