我正在 dotnet core 2.2 中处理 API,我想对我的 API 进行版本控制。 我正在寻找一些解决方案,除了:
我想知道是否还有其他无需更改路由属性的解决方案?我可能完全错了,但我可以使用中间件吗?例如,映射委托将传入的请求(基于它携带的 v1、v2)映射到其正确的控制器?
我将非常感谢任何反馈和建议。
答案 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 需要从请求中解析 API 版本,但它不知道或不了解您的路由模板。例如,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}
:
归根结底,这个要求是通过 URL 段进行版本控制的另一个结果,这就是我不推荐它的原因。 URL 段版本控制是所有版本控制方法中 RESTful 最少的(如果您关心的话),因为它违反了统一接口约束。所有其他开箱即用的受支持的版本控制方法都没有此问题。
为了清楚起见,开箱即用的支持方法是:
n
方法的组成(例如:查询字符串 + 标头)您还可以通过实现 IApiVersionReader 来创建自己的方法。
属性只是可以应用 API 版本的一种方式。换句话说,如果您不想,您不必使用 [ApiVersion]
属性。您还可以使用 conventions fluent API 或创建自己的 IControllerConvention。 VersionByNamespaceConvention 是此类约定的示例,它从包含的 .NET 命名空间派生 API 版本。您可以创建和映射自己的约定的方法几乎是无限的。