【问题标题】:Swagger: I need versioning AND groupingSwagger:我需要版本控制和分组
【发布时间】:2021-10-17 16:19:03
【问题描述】:

使用 .Net 5 REST API 招摇。

我有一个包含数百种方法的 API,需要将相关 API 组合在一起。同时,我需要开始开发我的 API 的 V2 版本。我花了几个小时尝试不同的方法来实现版本控制和分组,但没有成功。

我有几个控制器,一些用于 V1,一些用于 V2。有人可以提供一个完整的例子吗?

【问题讨论】:

标签: asp.net-core swagger grouping api-versioning


【解决方案1】:

在提出解决方案之前,让我先说明几点:

  • 上面的 YouTube 视频和 @abdusco 在他们看来提供了他们自己的 API 版本控制方法,但问题是关于 ASP.NET Core API Versioning
  • 虽然未指定,但我假设您没有按 URL 段进行版本控制
  • 默认的 OpenAPI/Swagger UI 只有一个枢轴点(例如组),您可以在下拉列表中选择它
  • OpenAPI/Swagger 文档必须具有唯一的 URL,这意味着您不能在同一个文档中拥有多个 API,除非您按 URL 段进行版本控制(最差的选择;最少的 RESTful)
  • Swagger,我猜你的意思是 Swashbuckle。 Swashbuckle OpenAPI 生成器使用ApiDescription.GroupName 在每个组的单个文档中整理 API,映射到 UI 中的下拉列表。改变这种行为是可能的,但并非易事。
  • API 版本控制的 API Explorer 扩展的默认行为将 ApiDescription.GroupName 设置为格式化的 API 版本值,如果没有另外设置,以便 API 按版本分组。在4.1 之前,[ApiExplorerSettings(GroupName="...")] 被忽略并覆盖。

归根结底,您需要两个分组维度:类别API版本。不幸的是,API Explorer、OpenAPI/Swagger UI 和 Swashbuckle 本质上只支持其中一种。开箱即用不支持任何形式的层次结构。有几种方法可以解决这个问题:

  1. group nameAPI version 连接为一个维度
  2. 创建一个 Swashbuckle 扩展(例如:IOOperationFilter)为特定组添加 OpenAPI 标记。然后可以更改 UI 以根据这些标签添加第二个下拉列表以进行过滤,或者标签可用于整理组(想想 Expander 控件)。
  3. 按 URL 段版本,生成单个 OpenAPI 文档,以您想要的方式更新 GroupName(此方法推荐)

可能还有更多选择,但这些是最明智的。虽然它可能不是您所希望的,但考虑到使用的限制,#3 是最直接实施的方法。它看起来像这样:

public class SubgroupDescriptionProvider : IApiDescriptionProvider
{
    private readonly IOptions<ApiExplorerOptions> options;

    public SubgroupDescriptionProvider(IOptions<ApiExplorerOptions> options)
        => this.options = options;

    // Execute after DefaultApiVersionDescriptionProvider.OnProvidersExecuted
    public int Order => -1;

    public void OnProvidersExecuting(ApiDescriptionProviderContext context) { }

    public void OnProvidersExecuted(ApiDescriptionProviderContext context)
    {
        var format = options.Value.GroupNameFormat;
        var culture = CultureInfo.CurrentCulture;
        var results = context.Results;
        var newResults = new List<ApiDescription>(capacity: results.Count);

        for (var i = 0; i < results.Count; i++)
        {
            var result = results[i];
            var apiVersion = result.GetApiVersion();
            var versionGroupName = apiVersion.ToString(format, culture);

            // [ApiExplorerSettings(GroupName="...")] was NOT set so
            // nothing else to do
            if (result.GroupName == versionGroupName)
            {
                continue;
            }

            // must be using [ApiExplorerSettings(GroupName="...")] so
            // concatenate it with the formatted API version
            result.GroupName += " " + versionGroupName;

            // optional: add version grouping as well
            // note: this works because the api description will appear in
            // multiple, but different, documents
            var newResult = result.Clone();

            newResult.GroupName = versionGroupName;
            newResults.Add(newResult);
        }

        newResults.ForEach(results.Add);
    }
}

然后您使用以下代码向 DI 注册:

services.TryAddEnumerable(
    ServiceDescriptor.Transient<IApiDescriptionProvider, SubgroupDescriptionProvider>());

如果您使用两组分组,那么您将获得多个 OpenAPI 文档。

按 API 版本(默认)

├─ v1
│   ├─ /utility
│   └─ /not-utility
└─ v2
    ├─ /utility
    └─ /not-utility

按组名 + API 版本

├─ Utilities v1   
│   └─ /utility
├─ Not Utilities v1
│   └─ /not-utility
├─ Utilities v2
│   └─ /utility
└─ Not Utilities v2
    └─ /not-utility

如果您的版本控制策略类似于N-2,那么列表应该是合理的。它是group * version 的产品,因此列表将取决于您最终拥有多少组和版本。

拥有一个真正的二维层次结构应该在技术上是可行的,但我从来没有做过,也不知道有人愿意付出努力来实现它。解决方案将非常具体地适用于您的 API 集。

【讨论】:

  • 感恩是我试图在自己身上培养的一个重要的个人特质,但坦率地说,我对 Swagger/Swashbuckle 的了解有限,我根本不知道如何处理你的例子。我不知道我应该如何实现版本控制,也不知道我需要如何注释我的控制器和 API 以配合您的建议。根本没有足够的信息让我从端到端构建它。我应该使用此示例进行版本控制吗? jones.bz/web-api-versioning-with-swagger
  • 好的。我知道了。我的印象是你已经熟悉这些概念,只是想定制一些东西。我们应该退后一步。我建议从结合了 API 版本控制和 Swashbuckle 的 Swagger Example 开始。这是一个全面的例子,你可以运行和玩耍。 如何您想要版本是非常主观的。如果您关心 RESTful,那么您应该选择媒体类型协商或查询字符串方法。
  • 我已尽我所能在wiki 中投入了大量精力。那里有大量信息,涵盖了许多选项和变化。现在网上也有很多不同的帖子、视频,甚至培训课程,但我并不赞同其中一个。我很高兴回答澄清问题。在使用 OpenAPI/Swagger/Swashbuckle 之前,最好先熟悉版本控制的工作原理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
  • 2020-09-28
  • 2022-08-12
  • 2018-11-13
  • 2021-11-30
  • 1970-01-01
相关资源
最近更新 更多