首页 文章

当我有多个版本的API时,如何填充swagger文档的基本路径?

提问于
浏览
0

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

但是,我想重构swagger文档,以便更好地使用basepath属性 .

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

我已经尝试创建一个DocumentFilter,它让我很接近,但并非一直如此 . 是的,我可以访问 GroupName 属性(它包含版本字符串"v1"),但我的谓词显然失败了,因为 swaggerDoc.Info.Version 的值是"1.0" . 这就是今天 class 的样子:

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文档,然后再从文档中的路径中删除它 . 这也让我非常接近,但失败了,因为没有为每个swagger文件执行 PreSerializeFilters ,但是一次(因此指定的最后一个basepath将在所有生成的文档中使用) . 这是我使用 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;
                });
            }
        });

任何人都可以帮我走最后一英里,让我按照自己喜欢的方式工作吗?

1 回答

  • 0

    有几种方法可以使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;
        }
    }
    

    我希望有所帮助 .

相关问题