【问题标题】:How can I populate the basepath of a swagger document when I have multiple versions of my API?当我有多个版本的 API 时,如何填充 swagger 文档的基本路径?
【发布时间】:2018-09-14 06:17:57
【问题描述】:

我正在使用 Swashbuckle.AspNetCore 来生成我的招摇文档,并且我正在使用 ApiVersion 来对我的控制器进行版本控制。我的设置支持多个版本,这很好用。这意味着我可以在 Swagger UI 中选择一个版本,并且我为每个版本创建了一个 swagger 文档,其中只有相关的操作。

但是,我想重构 swagger 文档以便更好地利用 basepath-property。

作为示例,让我使用为我的 API 版本 1 生成的 swagger 文档。本文档中所有路径均以"/api/v1/..."开头,生成的swagger文档中没有basepath。但是,我希望 让我的所有路径都以"/..." 开头,并且生成的文档包含一个值为"/api/v1" 的基本路径属性。

我尝试过创建一个 DocumentFilter,它让我很接近,但不是一直如此。没错,我可以访问GroupName 属性(它包含版本字符串“v1”),但我的谓词显然失败了,因为swaggerDoc.Info.Version 的值是“1.0”。这就是今天课程的样子:

public class SetBasePath : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        swaggerDoc.BasePath = $"/{context.ApiDescriptionsGroups.Items.Where(i => i.GroupName == swaggerDoc.Info.Version).Single().GroupName}";
    }
}

然后我尝试了另一种方法,使用PreSerializeFilters首先将基本路径添加到swagger文档中,然后再次将其从文档中的路径中删除。这也让我非常接近,但失败了,因为 PreSerializeFilters 不是为每个 swagger 文档执行的,而是一次(因此指定的最后一个基本路径将在所有生成的文档中使用)。这是我使用PreSerializeFilters的代码:

app.UseSwagger(c =>
{
    foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
    {
        var basepath = $"/api/{description.GroupName}";

        c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
        {
            swaggerDoc.Host = httpReq.Host.Value;
            swaggerDoc.BasePath = basepath;
        });

        c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
        {
            IDictionary<string, PathItem> paths = new Dictionary<string, PathItem>();
            foreach (var path in swaggerDoc.Paths)
            {
                paths.Add(path.Key.Replace(basepath, string.Empty, StringComparison.InvariantCulture), path.Value);
            }
            swaggerDoc.Paths = paths;
        });
    }
});

谁能帮我走最后一英里,并按照我想要的方式进行工作?

【问题讨论】:

标签: asp.net-core swagger asp.net-core-webapi swashbuckle api-versioning


【解决方案1】:

有几种方法可以使 ApiDescription 对象与 Swagger 文档版本匹配。您无法安全地反转 Swagger 文档版本;但是,由于您一开始就可以控制创建它,所以匹配起来并不难。您可能正在使用示例行为,如下所示:

new Info() { Version = description.ApiVersion.ToString() }

使用提供的扩展方法,您可以像这样在文档过滤器中匹配它:

public class SetBasePath : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        var docVersion = swaggerDoc.Info.Version;
        var groupName = (from descriptionGroup in context.ApiDescriptionGroups.Items
                         from description in descriptionGroup.Items
                         let apiVersion = description.GetApiVersion().ToString()
                         where apiVersion == docVersion
                         select descriptionGroup.GroupName).First();

        swaggerDoc.BasePath = "/api/" + groupName;
    }
}

希望对你有帮助。

【讨论】:

  • 虽然我必须在查询中从组更改为项组才能编译代码。您可能需要编辑您的分析器,以防有人试图复制粘贴它;)
猜你喜欢
  • 2020-06-24
  • 2022-08-12
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 2016-06-27
相关资源
最近更新 更多