【问题标题】:How to exclude default API route version from non-default version document如何从非默认版本文档中排除默认 API 路由版本
【发布时间】:2020-10-26 14:52:27
【问题描述】:

我有一个 ASP.NET Core (3.1) API,它使用 aspnet-api-versioning (4.1.1) 库进行版本控制。该项目设置为从 URL 读取版本,如果未指定版本,则使用默认版本 (1)。示例控制器支持两个 API 版本(1 和 2)并且有两个相同的方法,每个版本一个。由于支持默认版本,因此控制器上有两个 Route 属性,一个没有版本,一个有。

在为 API 生成 OpenAPI 文档时,使用 Swashbuckle.AspNetCore (5.6.3) 库,API 版本 1 和 2 的文档都将包含非版本化路由; “/客户/{externalCustomerId}”。要解决的问题是,如何将 Swagger 生成配置为仅包含默认版本的文档中的非版本化路由?鉴于下面的代码,版本 1 的文档应该是:

  • /客户/{externalCustomerId}
  • /v1/Customer/[externalCustomerId}

版本 2 的文档应该是:

  • /v2/Customer/{externalCustomerId}

启动:

public class Startup
{
    ... // Removed for brevity. Method below called from ConfigureServices(...).
    private static void ConfigureApiVersioning(IServiceCollection services)
    {
        services.AddVersionedApiExplorer(setup =>
        {
            setup.GroupNameFormat = "'v'V";
            setup.SubstituteApiVersionInUrl = true;
        });

        services.AddApiVersioning(setup =>
        {
            setup.AssumeDefaultVersionWhenUnspecified = true;
            setup.DefaultApiVersion = new ApiVersion(majorVersion: 1, minorVersion: 0);
            setup.ReportApiVersions = true;
            setup.ApiVersionReader = new UrlSegmentApiVersionReader();
        });
    }
}

控制器:

[Route("Customer")]
[Route("v{version:apiVersion}/Customer")]
[ApiVersion("1", Deprecated = true)]
[ApiVersion("2")]
[ApiController]
public class CustomerController : ControllerBase
{
    [HttpGet("{externalCustomerId}")]
    [MapToApiVersion("1")]
    public string Get()
    {
        return "Customer Api v1 responded with 200 ok";
    }

    [HttpGet("{externalCustomerId}")]
    [MapToApiVersion("2")]
    public string GetV2()
    {
        return "Customer Api v2 responded with 200 ok";
    }
}

可以(应该)以某种方式使用SwaggerGenOptions.DocInclusionPredicate() 解决它吗?我试了一下,但找不到从谓词的ApiVersion 获取默认 API 版本的方法。

一种选择可能是从DefaultApiVersionDescriptionProvider 继承(或实现IApiVersionDescriptionProvider)以访问Options 属性,这将允许我们获取默认API 版本并在Startup for @ 中使用带有闭包的谓词987654329@,但这是一个好方法吗?还有哪些其他选择?

【问题讨论】:

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


    【解决方案1】:

    有几种可能:

    • 使用DocInclusionPredicate
    • 使用自定义 IOOperationFilter
    • 使用自定义 IApiDescriptionProvider

    第一个可能是最简单的。由于所有正确版本的路由都包含路由参数,因此您只需排除任何包含它的路由。比如:

    c.DocInclusionPredicate((d, api) => !api.RelativePath.Contains("v{version:apiVersion}"))
    

    您需要删除/禁用options.SubstituteApiVersionInUrl;反正你没用。

    您应该仔细考虑您的 API 文档所传达的内容;这是误导。 OpenAPI/Swagger 文档将显示2.0 的正确路由;但是,当客户请求它时,他们会得到1.0。发生这种情况是因为您不允许指定任何版本并且您假设 1.0。您可以使用替代的 IApiVersionSelector,例如 CurrentImplementationApiVersionSelector,但这只会扭转问题。版本控制的目的是让客户可以明确要求他们想要的版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-17
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 2011-08-16
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多