我已经看到 //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 服务的客户端也应该是无知的。