问题描述
我认为我对 REST 了解的大量内容显然是错误的——而且我并不孤单.这个问题有很长的引入,但似乎是必要的,因为信息有点分散.如果您已经熟悉这个主题,那么实际问题就在最后.
A large amount of what I thought I knew about REST is apparently wrong - and I'm not alone. This question has a long lead-in, but it seems to be necessary because the information is a bit scattered. The actual question comes at the end if you're already familiar with this topic.
来自 Roy Fielding 的 REST API 必须超文本驱动,很明显他认为他的工作被广泛误解:
From the first paragraph of Roy Fielding's REST APIs must be hypertext-driven, it's pretty clear he believes his work is being widely misinterpreted:
我对将任何基于 HTTP 的接口称为 REST API 的人数感到沮丧.今天的示例是 SocialSite REST API.那就是RPC.它尖叫着 RPC.显示的耦合太多了,应该给它一个 X 评级.
Fielding 继续列出 REST API 的几个属性.其中一些似乎与 SO 和其他论坛上的常见做法和常见建议背道而驰.例如:
Fielding goes on to list several attributes of a REST API. Some of them seem to go against both common practice and common advice on SO and other forums. For example:
除了初始 URI(书签)和适用于预期受众的标准化媒体类型集(即,任何可能使用API)....
A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). ...
REST API 不得定义固定的资源名称或层次结构(客户端和服务器的明显耦合)....
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). ...
REST API 应该将几乎所有的描述性工作用于定义用于表示资源和驱动应用程序状态的媒体类型,或者用于定义扩展关系名称和/或支持超文本的标记现有的标准媒体类型....
A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. ...
超文本"的概念起着核心作用 - 比 URI 结构或 HTTP 动词的含义更重要.超文本"在评论之一中定义:
The idea of "hypertext" plays a central role - much more so than URI structure or what HTTP verbs mean. "Hypertext" is defined in one of the comments:
当我 [Fielding] 说超文本时,我的意思是信息和控件的同时呈现,这样信息就成为用户(或自动机)获得选择和选择动作的可供性.超媒体只是对在媒体流中包含时间锚点的文本含义的扩展;大多数研究人员已经放弃了这种区分.
超文本在浏览器上不需要是 HTML.当机器了解数据格式和关系类型时,它们可以跟随链接.
Hypertext does not need to be HTML on a browser. Machines can follow links when they understand the data format and relationship types.
我在猜测这一点,但上面的前两点似乎表明,如下所示的 Foo 资源的 API 文档会导致客户端和服务器之间的紧密耦合,并且在 RESTful 系统中没有位置.
I'm guessing at this point, but the first two points above seem to suggest that API documentation for a Foo resource that looks like the following leads to tight coupling between client and server and has no place in a RESTful system.
GET /foos/{id} # read a Foo
POST /foos/{id} # create a Foo
PUT /foos/{id} # update a Foo
相反,应该强制代理发现所有 Foo 的 URI,例如,通过针对/foos 发出 GET 请求.(这些 URI 可能会遵循上面的模式,但这不是重点.)响应使用能够传达如何访问每个项目以及可以用它做什么的媒体类型,从而产生了上面的第三点.因此,API 文档应侧重于解释如何解释响应中包含的超文本.
Instead, an agent should be forced to discover the URIs for all Foos by, for example, issuing a GET request against /foos. (Those URIs may turn out to follow the pattern above, but that's beside the point.) The response uses a media type that is capable of conveying how to access each item and what can be done with it, giving rise to the third point above. For this reason, API documentation should focus on explaining how to interpret the hypertext contained in the response.
此外,每次请求 Foo 资源的 URI 时,响应都包含代理发现如何继续操作所需的所有信息,例如,通过其 URI 访问关联资源和父资源,或采取行动在创建/删除资源之后.
Furthermore, every time a URI to a Foo resource is requested, the response contains all of the information needed for an agent to discover how to proceed by, for example, accessing associated and parent resources through their URIs, or by taking action after the creation/deletion of a resource.
整个系统的关键是响应由包含在媒体类型中的超文本组成,该媒体类型本身传达给代理选项以进行处理.这与浏览器为人类工作的方式没有什么不同.
The key to the entire system is that the response consists of hypertext contained in a media type that itself conveys to the agent options for proceeding. It's not unlike the way a browser works for humans.
但这只是我在这个特定时刻最好的猜测.
But this is just my best guess at this particular moment.
Fielding 发布了一篇跟进,其中他回应批评他的讨论是太抽象,缺乏例子,行话丰富:
Fielding posted a follow-up in which he responded to criticism that his discussion was too abstract, lacking in examples, and jargon-rich:
其他人会尝试以更直接或更适用于当今某些实际问题的方式来解读我所写的内容.我可能不会,因为我太忙于处理下一个主题,准备会议,编写另一个标准,去某个遥远的地方旅行,或者只是做一些让我觉得自己赚到了薪水的小事.
那么,有两个简单的问题要问具有实用思维的 REST 专家:您如何解释 Fielding 所说的内容以及在记录/实施 REST API 时如何将其付诸实践?
So, two simple questions for the REST experts out there with a practical mindset: how do you interpret what Fielding is saying and how do you put it into practice when documenting/implementing REST APIs?
这个问题是一个例子,说明如果您对所谈论的内容没有名字,那么学习是多么困难.本例中的名称是超媒体作为应用程序状态的引擎"(HATEOAS).
推荐答案
我认为您的解释主要涵盖了它.URI 是不透明的标识符,在大多数情况下,不应在用户代理用于访问应用的书签 URI 之外进行通信.
I think your explanation mostly covers it. URIs are opaque identifiers that should, for the most part, not be communicated beyond the bookmark URI that is used by the user agent to access the app.
至于记录,这个问题已经做过好几次了.您可以记录您的媒体类型及其包含的超链接控件(链接和表单)以及交互模型(如果您愿意)(请参阅 AtomPub).
As for documenting, this question has been done quite a few times. You document your media type, together with the hyperlink controls that it contains (links and forms), and the interaction model if you so wish (see AtomPub).
如果您记录了 URI 或如何构建它们,那么您就做错了.
If you document the URIs or how to build them, you're doing it wrong.
这篇关于那个 REST API 真的是 RPC 吗?罗伊·菲尔丁似乎是这么认为的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!