RESTful HATEOAS客户端URL

时间:2012-10-18 15:29:52

标签: rest hateoas

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

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

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

对于这类事情,是否有某种最佳做法?

2 个答案:

答案 0 :(得分: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,并且可以surf it in a browser并执行所有操作(在HTML和浏览器赶上HTTP之前,非POST表单提交可能需要AJAX),那么符合REST的超媒体约束。

从评论中提升

编辑

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

只是明确地说,网站是一种HTTP服务。 Web浏览器不会以不同方式处理不同的Web站点。要在Amazon上搜索产品,请在http://amazon.com/加载Amazon服务端点,并按照链接或填写该响应中提供的表单。要在易趣上搜索产品,请在http://ebay.com/加载易趣服务端点并执行相同操作。
浏览器事先并不知道为了搜索易趣,你必须这个,但是为了搜索亚马逊,你必须那个。浏览器是无知的。其他HTTP服务的客户端也应该是无知的。

答案 1 :(得分:0)

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

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

请记住,媒体类型的文档和资源允许的HTTP谓词并不违反RESTful原则。请查看SunCloud API以获取示例。

确实,根据你的例子,POST到

  

// somehost.com/resource

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

  

// somehost.com/resource/1/new

然后发布到

  

// somehost.com/resource

反正。