使用 HATEOAS 对耦合的 RESTful API 进行版本控制



我们有一个ProductsAPI来浏览我们网站上可用的产品,这些产品由我们的移动应用程序(Android和iOS(使用。以下是基本设计:

URL: /api/products/
Response:
[
{
"id" : 123,
"name" : "abc",
"detailsUrl" : "/api/products/123"
},
{
"id" : 124,
"name" : "xyz",
"detailsUrl" : "/api/products/124"
}
]

在这里,detailsUrl包含ProductDetails页面的 API URL。

现在,我们需要在新版本的应用程序中对ProductDetailsAPI 的响应进行一些更改,并且需要对其进行版本控制。URL 将更改为 -/api/v2/products/{id}(我们通过 URL 使用 API 版本控制(。

由于我们不希望在以前版本的应用程序中出现新的响应,因此我们还需要创建一个新版本的ProductsAPI,该版本将发送新的ProductDetailsAPIurl 作为响应。

API 以这种方式耦合。如果我们更改任何子 API 的版本,则还需要更改父 API 版本。处理此问题的推荐方法是什么?我们应该改变对 API 进行版本控制的方式(使用标头或其他东西(吗?

这是 URL 段中版本控制的结果之一。我建议不要这样做。对于 HATEOAS,超媒体应仅报告相关资源的身份。由客户端决定他们要使用的 API 版本。

在大型 API 中,服务具有不一致的版本是很常见的。这会导致在提供的链接中包含 API 版本的任何方法出现许多问题。

  1. 播发链接的服务现在要么假设相关资源具有相同的资源版本,要么具有不需要的耦合以生成正确的链接
  2. 该服务不知道客户端想要或与哪个 API 版本保持一致。客户端可能正在使用api/orders1.0 和api/salespeople2.0。服务无法知道这一点,这是客户端的责任。如果服务在链接中烘焙版本,它可能不是客户端想要的,使其在 HATEOAS 上下文中几乎毫无价值

在我看来,api/products/123api/v2/products/123之间没有逻辑上的区别.归根结底,两个URL都引用标识符为123的产品。API 版本指示该产品的不同表示形式,但不指示不同的产品。为此,HATEOAS 实现应以api/products/123的形式返回链接,并让客户端使用查询字符串、标头、媒体类型等按 API 版本决定表示形式。URL 段方法是唯一不能以这种方式工作的方法。

我建议使用一个全新的版本,这样父级和子级都会在他们的URL中添加一个/v2,或者使用媒体类型。 媒体类型的思想是客户端发送内容类型标头,以指定应为每个资源返回哪个版本的响应。 使用此方法可以避免对整个 API 进行重新版本控制,但确实意味着对每个终结点进行版本检查。

使用 GitHub API 是正在使用的媒体类型的一个很好的例子,您可能会发现阅读此处的文档很有用:https://developer.github.com/v3/media/