罗伊·菲尔丁写道
REST API 不得定义固定
资源名称或层次结构(
客户端和客户端的明显耦合
服务器)。服务器必须有自由
来控制自己的命名空间。
相反,允许服务器指示
客户如何构建
适当的 URI,例如在
HTML 表单和 URI 模板,作者:
定义这些指令
媒体类型和链接关系。
如何为系统间接口做到这一点?假设客户端想要在服务器 http://my.server.org 上创建订单,该怎么办要了解创建订单应该使用 url http://my.server.org/newOrder 而不是 http://my.server.org/nO 或其他什么?
对于人机界面(即浏览器),我猜服务器会提供某种形式的链接(可能在 form
元素中),并且该链接周围和中的文本将告诉用户哪个表单在该页面是创建订单的正确页面(假设创建用户或导航到某些搜索结果)
在客户端实现此操作的机制是什么?另外:它们是否实际使用过,还是大多数人只是将 URL 硬连接到客户端?
Roy Fielding writes
A REST API must not define fixed
resource names or hierarchies (an
obvious coupling of client and
server). Servers must have the freedom
to control their own namespace.
Instead, allow servers to instruct
clients on how to construct
appropriate URIs, such as is done in
HTML forms and URI templates, by
defining those instructions within
media types and link relations.
How do you do this for system-to-system interfaces? Say the client wants to create an order in the server at http://my.server.org How is it supposed to learn that for creating an order it is supposed to use the url http://my.server.org/newOrder and not http://my.server.org/nO or anything else?
For a human interface (i.e. browser), I guess the server would provide some form of link (possibly in a form
element) and the text around and in that link would tell a user which of the forms on that page is the correct one for creating an order (as supposed to creating a user or navigating to some search result)
What are the mechanics used for implementing this on the client side? And also: are they actually used or does the majority of people just hardwire the urls into the client?
发布评论
评论(3)
它不会学习。一般来说,机器客户端无法“学习”。至少现在还没有,我们仍处于天网之前。你必须“教导”他们。
但关键是你不教他们网址。你教他们关系。
考虑一下,在 HTML 中...
您会
注意到 rel 是相同的“顺序”,但 URL 却不同。
在“完美”的世界中,您的系统将有一个入口点,例如 http://my.server.org/ 和从那里,客户端可以找到它需要了解的所有关系。
实际上,许多系统都有几个“众所周知的”且已定义的入口点,客户端可以从这些入口点启动,这只是一种权宜之计,因此客户端不必总是从系统的根启动。这些众所周知的入口点有提供商的隐含承诺,即这些 URL 不会很快发生更改。它们的寿命很长,并且服务器会很好地支持它们。
但一旦通过了入口点,您发现的任何 URL 背后都可能没有这样的承诺。 URL 可以是仅供使用的 URL。它可以被定向到不同的机器,例如负载平衡。谁知道呢。但作为服务的消费者,您实际上并不关心 URL 是什么,您只关心关系。该关系告诉您要使用的 URL 的详细信息。
超媒体 API 的文档解释了如何将统一的接口应用于您的客户端将遇到的每个关系。客户也无法“凭直觉”知道这一点,必须经过教导。
基本上,通过教导客户端如何导航它将或可能在其处理的有效负载中找到的关系,就是客户端操纵超媒体 API 的方式。有效负载包含指示道路的路标,但服务器决定这些路标的去向。
至于它的使用频率,在机器对机器的世界中,可能不是很多。大多数系统都不够大,URL 的更改不足以产生影响,而且客户端也很少,因此更改客户端并不是一个重大负担。所以大多数只是硬编码。
但最终,你只会遇到不好的客户。 REST 系统对不良客户端无能为力。无论如何,它无法在运行时区分它们。
It doesn't learn. Machine clients, generally, can't "learn". Not yet at least, we're still pre-Skynet. You have to "teach" them.
But what the key is that you don't teach them URLs. You teach them relations.
Consider, in HTML...
and
You'll notice that the rel is the same, "order", but the URL is not.
In a "perfect" world, you system will have a single entry point, say, http://my.server.org/ and from there the client can find all of the rels that it needs to know about.
In practice, many systems have several "well known", and defined entry points from which the client can start, just as an expediency so the client does not alway have to start at the root of the system. These well known entry points have an implied commitment from the provider that these URLs won't be changing any time soon. That they're long lived, and the server will support them very well.
But once passed the entry point, any URL you find likely does not have such a promise behind it. The URL can be a one use only URL. It could be directed to different machines for, say, load balancing. Who knows. But as a consumer of the service, you really don't care what the URL is, you only care about the relation. The relation tells you the detail of the URL to use.
The documentation of your hypermedia API explains how to apply the uniform interface to each of the rels that your client will encounter. The client can't "intuit" that either, it has to be taught.
Basically, by teaching the client how to navigate the relations that it will or MAY find in the payloads it processes is how the client manipulates the hypermedia API. The payloads contain sign posts to show the way, but the server dictates where those sign posts go.
As for how often it is used, in the machine to machine world, likely not very much. Most systems aren't large enough where the URLs change enough to matter, and the clients are so few that changing the clients is not a significant burden. So most just hard code away.
But then, in the end, you just have bad clients. Nothing a REST system can do with a bad client. It can't tell them apart at runtime anyway.
无论您如何发布 API(供机器使用),都可能做出重大更改。
将 API 包装在 UI(例如 HTML 表单)后面时,您可以自由更改 URI,而不会破坏用户,但这是因为用户正在使用您提供的抽象。在不更改表单的情况下更改 URL 架构,您仍然会破坏客户端。
避免破坏机器客户端的几种方法(基本上,支持向后兼容性):
No matter how you publish an API (to be consumed by machines), it is possible to make breaking changes.
When wrapping your API behind a UI (such as HTML forms), you have the freedom to change the URI without breaking the user, but that is because the user is consuming an abstraction you provided. Change the URL schema without changing your form, and you'll still break the client.
A couple ways to avoid breaking machine clients (basically, supporting backward-compatibility):
我们通过以下方式非常成功地解决了这个问题:在应用程序的根 URL 公开一个 WADL 文件,描述媒体类型以及在哪里可以找到其中的链接及其语义。我知道 REST 社区中的一些人认为这一点 (WADL) 至关重要,但我总是对 WADL 仅关注 URL 感到害怕。除了所有的宗教辩论之外,我们还喜欢有一种明确的方式来记录陈述。有一种方法可以绕过 WADL 的 URL 焦点,而是指出可以在表示中找到链接的位置,然后记录该内容。请参阅该博文(目前由于维护而关闭,因此你可能想在Google 缓存)了解该方法的详细信息。
这导致客户端只知道一个 URL,因为他可以找到它访问 WADL 的信息,从那时起,只需了解表示形式和在哪里可以找到链接、调用什么 HTTP 方法需要什么参数等等在。
We've quite sucessfully approached it the following way: expose a WADL file at the very root URL of the application describing the media types as well as where to find links in it and their semantics. I know this (WADL) is something seen critical by some in the REST community but I always felt intimidated by very URL focus of WADL only. Beyond all the religious debates we liked having a well defined way of documenting representations. There is a way to get around the URL focus of WADL and rather point out where links can be found in the representation and then rather document that. See that blog post (currently down because of maintenance so you might want to look at it in the Google cache) for details on the approach.
This results in only a single URL to be known by the client as he can find out about it accessing the WADL, and from then on just learn about the representation and where to find links, what HTTP method needs what parameters when being invoked and so on.