简体   繁体   English

RESTful HATEOAS客户端URL

[英]RESTful HATEOAS Client Url

I'm reasonably sure I understand the server-side of HATEOAS design - returning state URL's in the response - but I'm slightly confused about how to design a client to accept these. 我有理由相信我理解HATEOAS设计的服务器端 - 在响应中返回状态URL - 但我对如何设计客户端来接受这些有点困惑。

For instance, we access a resource at //somehost.com/resource/1 - this provides us with the resource data and links. 例如,我们在//somehost.com/resource/1访问资源 - 这为我们提供了资源数据和链接。 We'll assume POST to //somehost.com/resource is returned, indicating a 'new' action. 我们将假设返回//somehost.com/resource的POST,表示“新”操作。 Now I understand posting some data to that url creates a new resource, and provides a response, but where does the form to post that data reside? 现在我理解将一些数据发布到该URL创建一个新资源,并提供响应,但发布该数据的表单在哪里? I've seen implementations where //somehost.com/resource/1/new provides a form which POSTS to /resource, but that URL itself contains a verb, and seems to violate REST. 我已经看到了//somehost.com/resource/1/new提供了一个POSTS到/ resource的表单的实现,但是这个URL本身包含一个动词,并且似乎违反了REST。

I think my confusion lies in that I'm implementing a RESTful API and a client to consume it, within the same application. 我认为我的困惑在于我在同一个应用程序中实现了一个RESTful API和一个客户端来使用它。

Is there some sort of best-practice for this sort of thing? 对于这种事情,有某种最佳实践吗?

I've seen implementations where //somehost.com/resource/1/new provides a form which POSTS to /resource, but that URL itself contains a verb, and seems to violate REST. 我已经看到了//somehost.com/resource/1/new提供了一个POSTS到/ resource的表单的实现,但是这个URL本身包含一个动词,并且似乎违反了REST。

This is incorrect. 这是不正确的。 A URI containing a verb does not, in itself, violate any REST constraint. 包含动词的URI本身不会违反任何REST约束。 It is only when that URI represents an action that this becomes a violation. 只有当URI 表示一个违反行为的动作时。 If you can perform a GET request on the URL and receive some meaningful resource (such as a "create new resource" form), then that is perfectly RESTful, and good practice. 如果您可以对URL执行GET请求并接收一些有意义的资源(例如“创建新资源”表单),那么这是完全RESTful 和良好实践。

My own API is exactly as you describe: /{collection}/new returns a form. 我自己的API与您描述的完全一样: /{collection}/new返回一个表单。 /new is just shorthand for a hypothetical /new-resource-creation-form and still represents a noun, and only supports GET requests (HEAD, OPTIONS and TRACE not withstanding). /new只是一个假设/new-resource-creation-form简写,仍然代表一个名词,并且只支持GET请求(HEAD,OPTIONS和TRACE不能承受)。
What HATEOAS prohibits is the user agent being required to know, that in order to create a new resource, it must add /new to the name of the collection. HATEOAS禁止的是用户代理需要知道的是,为了创建新资源,它必须添加/new添加集合的名称。

Basically, if you implement your API as (X)HTML, and can surf it in a browser and perform all actions (AJAX may be required for non-POST form submissions until HTML and browsers catch up with HTTP), then it complies with the hypermedia constraint of REST. 基本上,如果您将API实现为(X)HTML,并且可以在浏览器中浏览它并执行所有操作(在HTML和浏览器赶上HTTP之前,非POST表单提交可能需要AJAX),那么它符合REST的超媒体约束。

EDIT promoted from comments: EDIT从评论中提升:

As long as the response negates any need for a priori knowledge, it conforms to the hypermedia constraint. 只要响应否定对先验知识的任何需要,它就符合超媒体约束。 If the client claims to understand HTML, and you send back a response containing a link to an external stylesheet or javascript (no matter where that is hosted) which the client needs to be able to render the page correctly, then it is reasonable to say that the constraint is met. 如果客户端声称理解HTML,并且您发回包含指向外部样式表或javascript(无论在何处托管)的链接的响应,客户端需要能够正确呈现页面,那么可以合理地说约束得到满足。 The client should know how to handle all media types it claims to support. 客户端应该知道如何处理它声称支持的所有媒体类型。 A normal human web browser is the perfect example of a client with no out-of-band knowledge about any one HTTP service (web site). 普通的人类Web浏览器是客户端的完美示例,没有关于任何一个HTTP服务(网站)的带外知识。

Just to say it explicitly, a web site is a kind of HTTP service. 只是明确地说,网站是一种HTTP服务。 Web browsers do not treat different web sites differently. Web浏览器不会以不同方式处理不同的Web站点。 In order to search for products on Amazon, you load the Amazon service endpoint at http://amazon.com/ and follow links or fill out forms provided in that response. 要在Amazon上搜索产品,请在http://amazon.com/加载Amazon服务端点,并按照链接或填写该响应中提供的表单。 In order to search for products on eBay, you load the eBay service endpoint at http://ebay.com/ and do the same. 要在eBay上搜索产品,请在http://ebay.com/加载eBay服务端点并执行相同操作。
Browsers don't know in advance that for searching eBay you must do this , but for searching Amazon you have to do that . 浏览器不事先知道搜索易趣必须这样做,但对于搜索亚马逊,你必须做到这一点 Browsers are ignorant. 浏览器是无知的。 Clients for other HTTP services should be ignorant too. 其他HTTP服务的客户端也应该是无知的。

Yes, you could provide a URI that returns a form for resource creation. 是的,您可以提供一个返回资源创建表单的URI。 Conceivably the form could be used for dynamic discovery of the elements needed to construct a new resource (but you'd want to decide how practical that would really be in a machine-to-machine environment). 可以想象,该表单可用于动态发现构建新资源所需的元素(但您需要决定在机器对机器环境中实际存在的实际情况)。

Unless there is a requirement that somehow the API has an exact browser-surfable equivalent, the documentation of the media type will describe what elements are needed. 除非要求 API以某种方式具有精确的浏览器可浏览的等价物,否则媒体类型的文档将描述所需的元素。

Remember that documentation of media types and the allowed HTTP verbs for a resource is not contrary to RESTful principles. 请记住,媒体类型的文档和资源允许的HTTP谓词并不违反RESTful原则。 Look at the SunCloud API for an example. 请查看SunCloud API以获取示例。

Indeed, according to your example, POST'ing to 确实,根据你的例子,POST'ing到

//somehost.com/resource //somehost.com/resource

to create a new resource is more standard than first returning a form 创建新资源比首先返回表单更标准

//somehost.com/resource/1/new //somehost.com/resource/1/new

and THEN POST'ing to 然后发布到

//somehost.com/resource //somehost.com/resource

anyway. 无论如何。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM