16

在设计 RESTful API 时,我们遇到了如何访问“同一对象”的不同版本的问题。假设页面对象由唯一键标识并通过 GET /api/page/pagekey 访问。它可以通过发送 PUT /api/page/pagekey 和正文中的适当文档来更新。

现在我们的系统会跟踪页面的旧版本,我们也希望通过 API 访问这些旧版本。让我们假设文档的旧版本是版本 1。似乎至少有两种方法可以设计 API 来访问这个特定版本的页面:

  1. 获取 /api/page/pagekey/1
  2. 获取 /api/page/pagekey?version=1

第一个变体将特定版本呈现为其自己的资源;第二个变体为现有资源提供了一个可选的版本上下文。

  • 变体 (1) 或 (2) 是更好的解决方案吗?还是有更好的方法来做到这一点?
  • 在变体 (1) 中,对不存在的版本号的请求,例如 /api/page/pagekey/7 可能会触发 HTTP 404 Not Found,这很方便。当考虑变体 (2) 时,这是否也是一个有效的状态响应,我们只更改现有资源的上下文“版本”,如果没有版本参数返回 HTTP 200 Ok 响应?
4

2 回答 2

9

每个资源 url 应该是一个永久链接来标识该资源。

GET /api/page/{id}/{rev}

这当然是特定版本资源的永久链接。所以,没关系。但请注意,永久链接不要求内容随着时间的推移保持不变:

GET /api/page/{id}

这将返回最新的版本,这很好,并且会随着时间的推移而改变内容。为了扩展它,你甚至可以拥有像这样的时间资源并且是 RESTful 的:

GET /api/page/latest 

但是,/api/page/{id}?version={rev}它也可以工作并且不会破坏任何 RESTful 概念。

我认为/{id}/{rev}它更纯粹一点,因为它在可寻址的 url 中专门标识了该资源,并且感觉比将其设置为参数更正确。原因是参数应该是关于如何检索内容的修饰符,而不一定会改变您正在检索的不同资源。在您的情况下,由于每个版本都是不同的,因此明确解决资源似乎更合适。但是,即使那个没有违反任何 RESTful url 规则或概念,如果你问了 10 个人,你可能会得到不同的答案 :)

无论哪种方式,您都应该确保临时资源/api/page/{id}返回最新版本。

于 2012-10-04T23:40:27.147 回答
0

几乎按照定义,REST 没有“相同对象”的概念。如果你在你的协议中需要这个,那么你需要有某种“标识符”。就如此容易 ;)

URL 参数是一种显而易见的方法。"/1" 或 "?version=1" 当然是两个不错的选择 - 您选择的只是一个偏好问题(以及您可能还想要多少“其他东西”的问题)。

无论哪种方式,您仍将不得不处理“未找到版本”类型的错误,并优雅地恢复。

恕我直言...

于 2012-10-04T23:35:09.730 回答