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

时间:2018-04-04 15:40:20

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

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

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

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

我尝试过创建一个DocumentFilter,它让我很接近,但并非一直如此。是的,我可以访问GroupName属性(其中包含版本字符串" v1"),但我的谓词显然失败了,因为swaggerDoc.Info.Version的值是" 1.0 &#34 ;.这就是今天班级的看法:

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,但是一次(因此指定的最后一个基道将用于所有生成的文档)。这是我使用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 :(得分: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;
    }
}

我希望有所帮助。