dotnet 核心中的 API 版本控制

时间:2021-06-24 07:21:24

标签: api .net-core api-versioning

我正在 dotnet core 2.2 中处理 API,我想对我的 API 进行版本控制。 我正在寻找一些解决方案,除了:

  1. 路由方式(api/v1/controller、api/v2/contoller)
  2. 使用 APIVersioning 包的路由方法,(api/v{version: apiVersion}/contoller})

我想知道是否还有其他无需更改路由属性的解决方案?我可能完全错了,但我可以使用中间件吗?例如,映射委托将传入的请求(基于它携带的 v1、v2)映射到其正确的控制器?

我将非常感谢任何反馈和建议。

2 个答案:

答案 0 :(得分:1)

您可以使用 APIVersioning 包并对其进行配置,以便它根据 HTTP 标头选择版本。

services.AddApiVersioning(c =>
{
   c.ApiVersionReader = new HeaderApiVersionReader("api-version");
}

然后您可以在控制器上使用 [ApiVersion] 属性。

答案 1 :(得分:0)

您可以使用自定义中间件吗 - 是的;但是,请注意端点选择通常涉及更多。路由系统提供扩展和定制点,这正是 API Versioning 为您所做的。与必须添加路由模板参数相比,创建自己的版本控制解决方案要复杂得多。

如果您要按 URL 段进行版本控制,则 API 版本控制要求您使用 ApiVersionRouteConstraint。默认名称注册为 apiVersion,但您可以通过 ApiVersioningOptions.RouteConstraintName 更改它。路由参数名称本身是用户定义的。您可以使用任何您想要的名称,但 version 是常见且含义明确的名称。

为什么需要路由约束? API Versioning 需要从请求中解析 A​​PI 版本,但它不知道或不了解您的路由模板。例如,ASP.NET 如何知道 id 中的路由参数 values/{id:int} 是一个没有 int 约束的整数?简短的回答 - 没有。 API 版本的工作方式相同。您可以根据需要编写路由模板,API 版本控制知道如何以及在何处使用路由约束提取值。 API 版本控制绝对做的是魔术字符串解析。这是一个非常有意的设计决定。 API 版本控制不会尝试自动神奇从请求 URL 中提取或解析 API 版本值。同样重要的是要注意 v 前缀对于 URL 段版本控制非常常见,但它不是 API 版本的一部分。使用路由约束的方法不需要 API Versioning 来担心 v 前缀。如果需要,您可以将其作为文字包含在路由模板中。

如果问题或顾虑是必须在您的路由模板中重复包含 API 版本约束,那么这与在每个模板中包含 api/ 前缀(我认为您正在这样做)实际上没有什么不同。通过使用以下其中一种方法可以很容易地保持 DRY,其中可以包括所有 API 路由的前缀 api/v{version:apiVersion}

  1. 扩展 RouteAttribute 并在所有模板前加上前缀;这是最简单的
  2. 滚动您自己的属性并实现IRouteTemplateProvider

归根结底,这个要求是通过 URL 段进行版本控制的另一个结果,这就是我不推荐它的原因。 URL 段版本控制是所有版本控制方法中 RESTful 最少的(如果您关心的话),因为它违反了统一接口约束。所有其他开箱即用的受支持的版本控制方法都没有此问题。

为了清楚起见,开箱即用的支持方法是:

  • 按查询字符串(默认)
  • 按标题
  • 按媒体类型(最 RESTful)
  • 按网址段
  • n 方法的组成(例如:查询字符串 + 标头)

您还可以通过实现 IApiVersionReader 来创建自己的方法。

属性只是可以应用 API 版本的一种方式。换句话说,如果您不想,您不必使用 [ApiVersion] 属性。您还可以使用 conventions fluent API 或创建自己的 IControllerConventionVersionByNamespaceConvention 是此类约定的示例,它从包含的 .NET 命名空间派生 API 版本。您可以创建和映射自己的约定的方法几乎是无限的。