我们有一个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。
现在,我们需要在新版本的应用程序中对ProductDetails
API 的响应进行一些更改,并且需要对其进行版本控制。URL 将更改为 -/api/v2/products/{id}
(我们通过 URL 使用 API 版本控制(。
由于我们不希望在以前版本的应用程序中出现新的响应,因此我们还需要创建一个新版本的ProductsAPI
,该版本将发送新的ProductDetailsAPI
url 作为响应。
API 以这种方式耦合。如果我们更改任何子 API 的版本,则还需要更改父 API 版本。处理此问题的推荐方法是什么?我们应该改变对 API 进行版本控制的方式(使用标头或其他东西(吗?
这是 URL 段中版本控制的结果之一。我建议不要这样做。对于 HATEOAS,超媒体应仅报告相关资源的身份。由客户端决定他们要使用的 API 版本。
在大型 API 中,服务具有不一致的版本是很常见的。这会导致在提供的链接中包含 API 版本的任何方法出现许多问题。
- 播发链接的服务现在要么假设相关资源具有相同的资源版本,要么具有不需要的耦合以生成正确的链接
- 该服务不知道客户端想要或与哪个 API 版本保持一致。客户端可能正在使用
api/orders
1.0 和api/salespeople
2.0。服务无法知道这一点,这是客户端的责任。如果服务在链接中烘焙版本,它可能不是客户端想要的,使其在 HATEOAS 上下文中几乎毫无价值
在我看来,api/products/123
和api/v2/products/123
之间没有逻辑上的区别.归根结底,两个URL都引用标识符为123的产品。API 版本指示该产品的不同表示形式,但不指示不同的产品。为此,HATEOAS 实现应以api/products/123
的形式返回链接,并让客户端使用查询字符串、标头、媒体类型等按 API 版本决定表示形式。URL 段方法是唯一不能以这种方式工作的方法。
我建议使用一个全新的版本,这样父级和子级都会在他们的URL中添加一个/v2
,或者使用媒体类型。 媒体类型的思想是客户端发送内容类型标头,以指定应为每个资源返回哪个版本的响应。 使用此方法可以避免对整个 API 进行重新版本控制,但确实意味着对每个终结点进行版本检查。
使用 GitHub API 是正在使用的媒体类型的一个很好的例子,您可能会发现阅读此处的文档很有用:https://developer.github.com/v3/media/