3

我有理由确定我了解 HATEOAS 设计的服务器端——在响应中返回状态 URL——但我对如何设计客户端来接受这些有点困惑。

例如,我们访问 //somehost.com/resource/1 上的资源 - 这为我们提供了资源数据和链接。我们假设返回到 //somehost.com/resource 的 POST,表示一个“新”操作。现在我知道将一些数据发布到该 url 会创建一个新资源并提供响应,但是发布该数据的表单在哪里?我已经看到 //somehost.com/resource/1/new 提供了一个 POSTS 到 /resource 的表单的实现,但是该 URL 本身包含一个动词,并且似乎违反了 REST。

我认为我的困惑在于我在同一个应用程序中实现了一个 RESTful API 和一个使用它的客户端。

这种事情有某种最佳实践吗?

4

2 回答 2

5
我已经看到 //somehost.com/resource/1/new 提供了一个 POSTS 到 /resource 的表单的实现,但是该 URL 本身包含一个动词,并且似乎违反了 REST。

这是不正确的。包含动词的 URI本身并不违反任何 REST 约束。只有当该 URI表示一个操作时,这才成为违规。如果您可以对 URL 执行 GET 请求并接收一些有意义的资源(例如“创建新资源”表单),那么这就是完美的 RESTful和良好实践。

我自己的 API 和你描述的完全一样:/{collection}/new返回一个表单。/new只是一个假设的简写/new-resource-creation-form,仍然代表一个名词,并且只支持 GET 请求(不支持 HEAD、OPTIONS 和 TRACE)。
HATEOAS 禁止的是用户代理需要知道,为了创建新资源,它必须添加/new到集合的名称中。

基本上,如果您将 API 实现为 (X)HTML,并且可以在浏览器中浏览它并执行所有操作(在 HTML 和浏览器赶上 HTTP 之前,非 POST 表单提交可能需要 AJAX),那么它符合REST 的超媒体约束。

编辑从评论中提升:

只要响应否定了对先验知识的任何需求,它就符合超媒体约束。如果客户端声称理解 HTML,并且您发回包含指向外部样式表或 javascript(无论托管在何处)的链接的响应,客户端需要能够正确呈现页面,那么可以合理地说满足约束。客户端应该知道如何处理它声称支持的所有媒体类型。普通的人类 Web 浏览器是客户端对任何一个 HTTP 服务(网站)没有带外知识的完美示例。

明确地说,网站是一种 HTTP 服务。Web 浏览器不会以不同的方式对待不同的网站。为了在亚马逊上搜索产品,您需要加载亚马逊服务端点http://amazon.com/并点击链接或填写该响应中提供的表格。为了在 eBay 上搜索产品,您需要加载 eBay 服务端点http://ebay.com/并执行相同操作。
浏览器事先并不知道搜索 eBay 必须这样做但搜索 Amazon 必须这样。浏览器是无知的。其他 HTTP 服务的客户端也应该是无知的。

于 2012-12-03T08:55:12.580 回答
0

是的,您可以提供一个返回资源创建表单的 URI。可以想象,该表单可用于动态发现构建新资源所需的元素(但您需要确定这在机器对机器环境中的实际应用程度)。

除非要求API 以某种方式具有精确的浏览器可浏览等效项,否则媒体类型的文档将描述需要哪些元素。

请记住,媒体类型的文档和资源允许的 HTTP 动词并不违反 RESTful 原则。以SunCloud API为例。

事实上,根据你的例子,POST'ing to

//somehost.com/resource

创建新资源比首先返回表单更标准

//somehost.com/resource/1/new

然后发布到

//somehost.com/resource

反正。

于 2013-09-26T21:58:09.403 回答