x-ms-version标头是遗留的,仅为向后兼容而维护。事实上,自2012 年x-
引入RFC 6648以来,使用前缀的概念已被弃用。
在查询字符串中使用api-version是Microsoft REST API 指南的§12 版本控制中概述的官方约定之一。该指南还允许使用 URL 分段方法,但查询字符串方法是最多产的。
菲尔丁本人对 API 版本控制有非常强烈的看法——即不要这样做。实现版本化 REST API 的唯一普遍接受的方法是使用媒体类型协商。(例如accept: application/json;v=1.0
或accept: application/vnd.acme.v1+json
)。GitHub 以这种方式对其 API 进行版本控制。
虽然媒体类型协商遵守 REST 约束并且实现起来并不难,但它是最少使用的方法。原因可能有很多解释,但实际上至少还有 3 种其他非常常见的方法:通过查询字符串、通过 URL 段或通过标头。
撇开迂腐的想法不谈,最常见的形式可能是由于客户可以轻松访问服务。标头方法与使用媒体类型协商没有太大区别。如果要使用标头,则将accept
andcontent-type
标头与媒体类型协商一起使用是更好的选择。这给我们留下了查询字符串和 URL 段的方法。
虽然 URL 分段方法很常见,但它有一些大多数服务作者没有考虑到的缺陷。它的扩散很大程度上是,“嗯,[在此处插入公司]就是这样做的”。在我看来,URL 分段方法存在以下问题:
- URL 不稳定。它们随着每个新的 API 版本而随时间而变化。
- 作为统一接口的一部分,URL路径应该用来标识资源。如果您的 URL 路径是
api/v1/products/123
和api/v2/products/123
,则表示有两种不同的产品,这是不正确的。v1
vs v2
URL 段暗示了不同的表示。在所有 API 版本中,资源仍然是相同的逻辑产品。
- 如果您的 API 支持 HATEOAS,那么当您的资源版本控制不一致时,链接生成将是一个挑战。成熟的服务分类法和 REST 约束本身旨在帮助随着时间的推移发展服务和资源。期望它
api/orders
是 1.0 和api/products/123
支持 1.0-3.0 的引用行项目是完全可行的。如果版本号包含在 URL 中,那么服务应该生成什么 URL?它可以假定相同的版本,但这可能是错误的。任何其他选项都与相关资源耦合,可能不是客户想要的。服务无法知道客户端理解的不同资源的所有 API 版本。因此,服务器应该只生成普通资源标识符形式的链接(例如:api/products/123
) 并让客户端指定要使用的 API 版本。客户端对链接的任何其他操作都会大大降低支持 HATEOAS 的价值。当然,如果一切都是相同的版本或在相同的资源上,这可能不是问题。
- 保留资源链接的客户端可能会使图 2 和图 3 变得更加复杂。当 API 版本日落时,到资源的任何旧链接现在都会被破坏,即使资源仍然存在,尽管没有使用预期的但过时的表示。
这给查询字符串方法带来了一个完整的循环。虽然查询字符串确实会因 API 版本而异,但它是一个参数,而不是标识符的一部分(例如路径)。URL 路径对所有版本的客户端保持一致。客户端也很容易为他们理解的版本附加查询参数。API 版本通常也是数字的、基于日期的或两者兼而有之。有时他们也有地位。URL可以api/products/123?api-version=2018-03-10-beta1
说比.api/2018-03-10-beta1/products/123
总之,虽然查询字符串方法可能不是真正的 RESTful 方法来对资源进行版本控制,但它倾向于携带更多预期的特征,同时保持易于使用(这不是 REST 约束)。结合 Microsoft REST API 指南,这就是ASP.NET API 版本控制默认使用开箱即用的查询字符串方法的原因,即使所有这些方法都受支持。
希望这提供了一些有用的见解,即除了纯粹的偏好之外,不同的样式如何影响您的服务分类。