本文翻译自下面的链接,是作者“REST是新的SOAP”这篇文章的后续文章。
https://medium.freecodecamp.org/follow-up-to-rest-is-the-new-soap-the-origins-of-rest-21c59d243438
Here’s my follow-up to REST is the new SOAP: let’s talk about the Original REST
这是我的“REST是新的SOAP”这篇文章的后续文章:让我们来探讨原本的REST。
I’ve read the philosophical dissertations, so you don’t have to!
我已经读了REST相关哲学论文了,所以你不用再读了。
I expected my recent article (or “hipsteresque drunken rant,” as some called it), to get a barrage of criticism, under the motto “you haven’t understood anything about REST.” It indeed happened.
我预料到我的最近的文章(或者一些人称之为“嬉皮士似的醉酒后的乱语”),会招致一连串的批评,说“你根本没有理解REST”。
But it also sparked interesting debates, especially on Reddit and on Hacker News. It also struck a cord in numerous developers, who felt like heretics for doubting the almightiness of REST.
但是它也激起了有趣的讨论,尤其是在Reddit和黑客新闻上。它在很多感觉质疑REST的权威就像异教徒一样的开发者那里激起了反响。
To quote a particularly insightful summary of the resentment:
下面引用一下对怨恨的有洞察力的总结:
A simple RPC API spec takes minutes to define. ‘Rest’ifying takes much longer, there are a million little gotchas, no real standard. Everyone has a different opinion of how it should be done.
一个简单的RPC的API规范只需要花几分钟定义。而采用REST会花相当长的时间,有许多看法,但没有真正的标准。每个人都有一个如何来做的不同看法。
Data is spread across verbs, urls, query params, headers, and payloads. Everyone thinks everyone else doesn’t ‘get’ REST. If you try to suggest something other than REST in the office you become the subject of a witch hunt. It really is a cargo cult of pointlessness.
数据散落在动词、链接、查询参数、消息头、载荷上。每个人都认为其他人没有得到REST的精髓。如果你想建议REST之外的技术,你会成为政治迫害的对象。它事实上是无意义的狂热崇拜。
My co-workers have spent sooo much time trying to get Swagger to generate documentation correctly as well as generate client side APIs, and there are countless gotchas we are still dealing with. It really is SOAP 2.0, when a simple JSON/RPC protocol would have done fine.
我的工友已经花费了大量时间来让Swagger正确地生成文档和生成客户端API了,我们还在解决无数的问题。它就是2.0版本的SOAP,本来用JSON/RPC协议的话事情早就做好了。
Don’t get me started with conflating HTTP server errors with applications errors. And trying to do action-like requests with a mindset optimized for CRUD. How much time have we wasted figuring out the ‘standard’ way to do just a login API call RESTfully.
不要让我合并HTTP服务端错误和应用错误。也不要期待我做查插删改请求这样的操作时有清晰的想法。有太多的时间浪费在找出标准的方法来做一个符合REST的登录API上了。
On the opposite side, Phil Sturgeon, one of the main advocates of REST, released a response article (see my quick comments here). I’m glad we agreed on some important points, especially that many APIs actually ought to be RPC, instead of ending as pseudo-REST patch-up jobs.
相反方面,Phil Sturgeon, 其中一个REST的主要倡导者,发布了一篇回应的文章(在这里参见我的快速的评论)。我很高兴我们在一些重要点上保持了一致,尤其是关于许多API实际上应该采用RPC,而不是打补丁的伪REST。
In the light of all this feedback, I’ve edited my initial essay quite a few times, and now a new article seems necessary to clarify the remaining points.
在所有这些反馈的照耀下,我很多次地修改了我的最初的文章,现在看起来一篇新的文章来澄清剩余的部分是必要的了。
I would like to apologize in advance if the cheekiness of this post comes across as rudeness. Considering the harmfulness of the situation, I alas couldn’t content myself of a peaceful tone. No personal offense is meant in any way. So let’s get on with it.
我想首先为我的厚脸皮的文章被一些人认为粗鲁道歉。考虑到这形势造成的伤害,我很遗憾我不能用和平一点的语调。我不想以任何方式冒犯任何人。所以,我们继续吧。
Several shades of REST
REST的几重色调
One difficulty of the subject is that there are several concepts behind the term “REST.”
这个主题的一个难点是在这个术语REST的背后有几个概念。
1) The Founding Book of REST, i.e the dissertation of Roy Fielding
1)REST的基础书,也就是Roy Fielding的论文
2) The thousands of blogposts/podcasts of REST advocates (like Phil Sturgeon’s), disseminated on the Web, and explaining “how to do REST properly”
2)数以千计的REST的倡导者(像Phil Sturgeon的)的解释如何正确地做REST的博客或播客
3) The gazillions of (self-proclaimed) RESTful webservices, publicly or privately exposed all over the Internet
3)极其大量的(自我宣称的)公开的或私有的暴露在互联网上的REST网络服务
My rant was mostly dealing with #3: the RESTish APIs that are wasting everyone’s time, for yet-to-be-demonstrated benefits. And even after reading hundreds of comments, I have to stand my ground: these APIs that I’ve met everywhere are constantly reinventing the wheel, don’t even leverage the advantages that HTTP semantics could bring (client-side caching, content negotiation, optimistic locking…), and are a lengthy pain to integrate.
我的演说大部分是针对第三种的:没有证明有什么益处,又浪费了所有人大量时间的REST风味的API。即使是读了数以百计的评论过后,我还是坚持我的立场:我在各处碰到的这些API是在持续地发明轮子,根本没有利用HTTP语义所能带来的优点(客户端缓存,内容协商,优化锁…),整合他们很痛苦。
The response article by Phil Sturgeon highlighted the main reason for this epitome of pointlessness:
Phil Sturgeon的回复文章强调了这些无意义行为的重点。
“Folks everywhere are building RESTish APIs which are basically just RPC + HTTP verbs + Pretty URLs.”
”有很多人在编写REST风味的API实际上只是RPC加上HTTP操作再加上漂亮的链接。“
Along the way, we evoked #2 through some quotes of REST advocates. For the rest, as far as I’ve seen, REST bloggers/podcasters have often contradicted each other. They’ve given instructions that sounded more like tastes than wisdom lessons, have evaded the most important questions, and have made a virtue of not backing, with examples and demonstrations, their most audacious arguments: “RPC causes redundant work”, “REST is necessary for APIs lasting decades”, and of course the (in)famous “The client does not need any prior knowledge of the service in order to use it.”
在这个过程,我们唤起了第二种类的许多REST的倡导者的引用。就我看到的,REST的许多博客和播客经常互相矛盾。他们给出听起来更多是口味而不是智慧的忠告,他们逃避了最重要的问题,他们不用例子和示范来支撑他们的最鲁莽的观点:”RPC导致重复的工作“,”REST对于需要持续几十年的API来说是必要的“,当然还有最著名的”客户端不需要预备知识来使用REST API“。
I’ve not yet crossed a simple page of prose summarizing how HATEOAS really works, and what challenges it solves for us. This is a problem in itself.
我还没有碰到简单的一页文章来概述HATEOAS如何真正工作,它解决了我们的什么问题。这本身就是个问题。
About contradictions…here’s an anecdote. When I showcased a simple (and gently CRUD-oriented) API, it was just to show the abnormal number of questions that had to be answered just to RESTify it. And still, numbers of commenters felt compelled to explain, with verbose documentation, how THEY would specify this API.
关于自相矛盾…这里有一个轶事。当我展示了一个简单的(温柔的基于查插删改的)API的时候,目的是展示为了REST化它需要解答多少异常的问题。仍然有相当多的评论感觉必须用冗长的文档解释说明这个API。
It resulted in lots of similar but incompatible protocols, some weaving standards together, some reinventing carved flintstone, and some going as far as specifying a versioned MIME type per Resource endpoint (like “application/vnd.my-rest-api.v1.account-search-result+json”).
这导致了许多相似的不兼容的协议,一些把各种规范编排一下,一些重复发明的雕刻的燧石,一些甚至绕远要为每种资源点指定一个有版本的MINE类型(类似“application/vnd.my-rest-api.v1.account-search-result+json”)。
Phil Sturgeon also answered, in his response article, these semi-rhetorical questions. The recommendations delivered made sense and seemed “up to date.” But they directly contradicted the past or present teachings of lots of other REST proponents (as well as commenters cited above) on diverse subjects: sparse fields, compounds documents, PATCH formats, DELETE payloads, and so on.
Phil Sturgeon也在他的回应文章中回答了这些准修辞学问题。他的这些建议有意义,并且看起来比较新。但是他们在许多主题上都与过去和现在的许多REST的倡导者的讲授(包括上边引用的评论)矛盾:稀疏字段,复合文档,补丁操作的格式,删除操作的载荷,等等。
At least all this proved a point: when things must be done quickly and consensually, REST is not the best way to go. Still, many claimed that I was attacking “misconceptions” of REST, and directed me to this or that quote from the original dissertation. This was a way of saying that the “theory” was good, even though the “practice” was flawed. “Yeah, right, communism claims the same,” one might argue.
所有这些都证明了一点:当事情必须很快且合意地完成的时候,REST不是最好的方式。仍然,很多人宣称我在攻击被误解的REST,然后把我引向这个或那个原始论文的引用。这是一种说明理论是好的,虽然实践有问题的方式。”是的,正确,共产主义也是这样宣称的。”有人可能会争论。
How some REST advocates view its Founding Thesis
一些REST的倡导者是如何看待它的基础论文的
The debate of whether a practice is RESTful or not has become a running gag in the web development ecosystem. However, for the sake of intellectual honesty, it was actually interesting to come back to the most authoritative definition of REST™ as given by the dissertation #1 and related articles. It’s at least to understand how this hype started, and what can be saved from it all.
对于一项实践是否是REST的争论已经成为万维网开发系统的可行的封口物。然而,从智力诚实上来说,实际上我们把焦点聚焦在定义REST的论文和相关文章上来实际上是很有趣的。这至少可以理解这狂热是如何开始的,和从其中可以拯救出什么。
I hope the summaries below will be deemed faithful enough to the originals. If not, I welcome your feedback on other “misconceptions” they might contain.
我希望下面的摘要是忠实于原作的。如果不是的话,我欢迎你对他们可能包含的其他错误的想法进行反馈。
What is the Original REST™ anyway?
究竟什么是原始的REST呢?
Roy Fielding’s dissertation, published in 2000, is naturally long (180 pages), so it’s probably not widely read among web developers.
Roy Fielding的论文发表于2000年,是自然地长(有180页),可能万维网开发者没有广泛地阅读。
Here is a breakdown of its content. As an alternative, you can also read the Introduction and Conclusion chapters of said dissertation.
这里是对它的内容的分解。作为替代方案,你还可以读上述论文的介绍和结论章节。
Chapter 1 defines architecture-related terms like elements, components, properties, styles, patterns, and so on.
第一章定义了架构相关的术语,例如元素,组件,属性,风格,模式,等等。
Chapter 2 lists the key properties for a network-based architecture: user-perceived performance, network efficiency, scalability, modifiability, visibility, and reliability.
第二章列出了网络相关架构的关键的属性:用户感知性能,网络效率,扩展性,修改性,可见性和可靠性。
Chapter 3 classifies existing architectural styles (Pipe and Filter, Cache, Client-Server, Code on Demand), and shows their pros and cons regarding the key properties above.
第三章分类了现有的架构风格(管道和过滤器,缓存,客户端服务器,按需编码),并且展示了他们对于上面的关键属性的优缺点。
Chapter 4 summarizes the requirements of the World Wide Web architecture (Low Entry Barrier, Extensibility, Distributed Hypermedia, Anarchic Scalability and so on), and explains why a dedicated architectural style is needed to guide its development, especially to evaluate proposed extensions before they are deployed.
第四章总结了万维网架构的需求(低入门门槛,扩展性,分布式超媒体,无政府的扩展性等),且解释了为什么某种架构风格是开发所需要的,尤其是在他们被部署之前评估建议的扩展。
Chapter 5 presents the REST architectural style: the existing styles from which it derives, its architectural elements (Resources and their Identifiers, Representations, Connectors, Components, and so on), and how all this works together regarding processes and data.
第五章展示了REST的架构风格:它从哪些现有风格发展而来,它的架构元素(资源和它们的标识,表示,连接,组件,等),还有所有这些流程和数据是如何工作的。
Chapter 6 gives an experience feedback of how REST was used to guide the development of Web protocol standards (URIs, HTTP and its numerous features and extensions), where it failed to be applied (cookies, mixing of different concerns in headers, user IDs in URIs, and so on), and the architectural lessons to be learned from the modern Web architecture.
第六章给出了基于经验反馈的REST如何指导了万维网协议的开发(URI,HTTP和它的许多特性和扩展),在哪些地方它应用失败(客户端储存信息,在消息头混合不同的关注切面,URI中的用户标识,等等),还有在现代的万维网架构中有哪些教训。
The book “An introduction to REST: Tome 1”
What do we get from this dissertation, apart from the usual REST constraints?
在”介绍REST:第一册”这本书中,我们从这篇论文中除了通常的REST限制外,得到了什么?
First, as expected from the introduction of an “architectural style,” it says almost nothing about HTTP methods, schemas, error handling, versioning, and all these concrete subjects which shape real-world webservices. That’s why hundreds of contradicting opinions have flowed to fill the hole, and that’s why it’s weird to sometimes hear that REST is “precisely specified” by this dissertation.
第一,不出意料,从架构风格的介绍来看,它几乎没有说任何关于HTTP方法的,比如大纲、错误处理、版本、和具体的构成真实世界的网络服务的这些主题。这就是为什么数百的矛盾的看法随之而至来填补漏洞的原因,这也是为什么有时听到REST被这篇论文精确地定义的说法时觉得怪异。
Second, REST was formalized to give a theoretical backbone to the development of the World Wide Web. It mixes lots of existing architectural styles, and inherits from their benefits and drawbacks, for the purpose of designing an Internet-scale distributed hypermedia system.
第二,REST被正规化,以给开发万维网提供理论支撑。为了设计适合互联网的分布式超媒体系统,它混和了很多现有的架构风格,继承了他们的优点和缺点。
And it works.
而且它能工作。
On the web, we are happy that all webpages speak HTTP, display themselves with a GET, and handle forms with GET or POST [Uniform Interface]
在万维网,我们高兴所有的网页都说HTTP,通过GET操作展示他们自己,用GET或POST统一的接口来操作表单。
On the web, we’re happy that our browser understands hundreds of content types (HTML, images, CSS, fonts, Javascript, RSS…), and handles them according to numerous built-in rules (caching, display, security…) [Self-Descriptive Messages]
在万维网,我们高兴我们的浏览器理解数以百计的内容类型(HTML,图片,层叠样式表,字体,Javascript,RSS…),并且依照内建的规则和自我描述的消息来处理他们(缓存,展示,安全…)
On the web, we’re happy to have in-browser caching, content delivery networks, and other forms of shared caches, helping to speed up loading time and absorb traffic peaks (like “Slashdot effects”). Even though a quick ctrl+F5 is sometimes needed to fix weird behaviors of webpages. [Layered System & Caching]
在万维网,我们高兴拥有浏览器内的缓存、内容分发网络和其他形式的共享的缓存,来帮助提高载入时间和吸收网络高峰(比如点杠效应)。虽然有时一个快速的”ctrl+F5”组合键需要用来修复怪异的网页的行为【分层系统和缓存】。
On the web, we’re happy that proxies and firewalls understand web protocols, and let them flow, while blocking dubious TCP/UDP connections. [Visibility]
在万维网,我们高兴代理和防火墙理解网络协议,让他们通过,同时而阻止可疑的TCP/UDP连接。【可视性】
On the web, we’re happy that scripts can be delivered by the server for each page, since browsers have, by themselves, no clue about how to add dynamics to provided HTML [Code-On-Demand]
在万维网,我们高兴脚本可以被服务器分发给每一个页面,因为浏览器自己没有迹象可以知道怎么在被给予的HTML上添加动态性。【按需编码】
One point evoked but not detailed in the dissertation is “Hypermedia As The Engine Of Application State” (HATEOAS). In complementary articles, Roy Fielding explained the concept of “hypermedia controls,” also called “affordances:” some kinds of glorified links, advertising to the client “what it can do next.” And he declared (a little late?) that these are not mere options, but that HATEOAS is at the very core of REST.
“在超媒体作为应用状态的引擎(HATEOAS, Hypermedia AS The Engine of Application State)”这篇论文中,有一点被引出但是没有被详述。在补充文章中Roy Fielding解释了”超媒体控制“的概念,也叫”功能可见性“:一些美其名的链接广告给客户端告诉它们下一步可以做什么。然后他宣称(是否有点迟?)这不是仅有的选项,但是HATEOAS是REST的核心。
When I say Hypertext, I mean … The simultaneous presentation of information and controls such that the information becomes the affordance through which the user obtains choices and selects actions. Hypertext does not need to be HTML on a browser: machines can follow links when they understand the data format and relationship types (source).
当我在说超文本的时候,我是说…同时展示文本和控制,这样信息变得可见,用户可以借此获取选择并选择行动。超文本不一定是浏览器上的HTML(Hyper Text Markup Language):机器如果能理解数据格式和关系类型,它们能够跟踪链接。
Information and actions, displayed up to a user through a self-documenting format of awesomeness, with a selection of links that turn a well-tuned client into a crawler instead of just being a CRUD exchange… well that’s the whole point of REST (source).
通过自我描述的令人敬畏的文档格式展示给用户信息和行为,通过选择链接,把协调好的客户端变成一个爬虫,而不仅仅是查插删改的交换…这是REST的整个观点(来源)。
Naturally, that is where I have to explain why “hypermedia as the engine of application state” is a REST constraint. Not an option. Not an ideal. Hypermedia is a constraint. As in, you either do it or you aren’t doing REST (source).
自然地,这是我必须解释为什么HATEOAS是REST的限制的地方。不是一个选项。不理想。超媒体是限制。就像你或者这样做,或者你没有依照REST的方法来做的选项一样(来源)。
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) (source).
对它的用户来说,一个REST的API应该除了初始的URI(书签)和一个集合的标准的适合用户的媒体类型之外不需要其它预备知识(就是说任何可能使用它的客户端都理解)。
Regarding this aspect too, the Web seems RESTful. From the homepage of a website, users and webspiders are able to navigate it effortlessly, and handle related medias (images, stylesheets, scripts, and so on) that are discovered along the way. Although URLs change over time and forms are added and removed, websites don’t need version numbers, and it’s fine.
从这一方面来看,万维网是符合REST的。从一个网站的主页,用户和网络爬虫能够不费力地操作和处理遇到的相关的媒体(图片,表格,脚本等等)。链接虽然会变化,表单可能增加或删除,网站不需要版本号,这很好。
When I realized that the main HATEOAS example was just the world wide web
We thus see that the original REST™ is a powerful architectural style, providing big control to servers over their clients, and offering a crawlable ecosystem of editable hypermedia.
当我意识到主要的HATEOAS例子仅仅是万维网的时候,我们就能够看到原本的REST是一个有力的架构风格,它通过客户端提供了对服务器的大的控制,也提供了可以抓取的可编辑超媒体的生态系统。
Now, what about your APIs? Do they aim at being “Internet-scale distributed hypermedia systems,” too?
现在,你的API怎么样?他们的目标也是互联网级别的分布式超媒体系统吗?
The hazardous and (often) unnecessary Holy Grail
有害的和(经常)不必要的圣杯
You might have heard about the Richardson Maturity Model. It evaluates the level of RESTfulness of your API, depending on whether it uses proper resources (Level 1), verbs (Level 2), and hypermedia controls (Level 3). This model might give you the feeling that some “RESTish” APIs of yours are meant to evolve on these “steps toward the glory of REST” (as Martin Fowler describes it). Bad news, this most probably won’t occur.
你也许听过Richardson成熟度模型。它通过它是否使用恰当的资源(第一层)、动词(第二层)和超媒体控制(第三层)评估你的API符合REST的等级。 这个模型可能给你一种感觉就是你的一些REST样子的API必然会沿着这些层级走向REST的辉煌(就像Martin Fowler描述的)。坏消息是,这大部分可能不会发生。
Yes, you can fake RESTfulness by mapping your server functions to Resource URLs. Yes, you can fake it further by mapping your operations to the closest HTTP verbs. But when it’s time to reach the final level, to really have a self-descriptive, crawlable, hypermedia-driven application, you’ll have to realize the harsh truth: your API is not RESTful, it has never been, and it never will be. It actually has less chances to attain “True RESTfulness” than a slug has to become a butterfly.
是的,你可以通过映射你的服务端的函数为资源链接来假装符合REST。是的你可以继续假装把你的操作映射为最接近的HTTP动词。但是当需要符合最后一级的时候,真正地达到自描述、可抓取、超媒体驱动的应用,你必须认识到残酷的事实:你的API不是REST的,从来都不曾会也不将会。事实上真的符合REST和一个鼻涕虫成为蝴蝶的几率一样。
Remember the quotes from Roy Fielding in the previous section? His definition of REST is all about HATEOAS. But it’s an extremely ambitious statement.
记得之前段落对Roy Fielding 的引用吗?他对REST的定义与HATEOAS强相关。但这是一个野心勃勃的宣称。
It means you should forget meaningless MIME types like “text/xml” or “text/json,” and use specific content types, backed by contracts, and recognizable by API consumers.
它意味着你应该忘记无意义的MIME类型如”text/xml”和”text/json”,而应该用具体的基于协议的被API使用者认识的类型。
It means that unless a full-fledged RESTful protocol already exists for your precise use case, you’ll have to write RFC/IETF-style drafts to describe the semantics of your specific content types.
这意味着除非针对你的精确的用例的REST协议已经存在,你将必须写RFC(Request for Comment)/IETF风格的草案来描述你的特定内容类型的规范。
You’ll have to design a crawler-enabled hypermedia system, and specify the meaning of its miscellaneous “affordances.” And you’ll probably have to provide client implementations to your customers, in their own programming languages, since they have other things to do than follow such herculean endeavors.
你将会必须设计一个支持爬虫的超媒体系统,然后指定各种可见性的含义。并且你可能会必须要提供客户端的实现给你的客户,还要用他们自己的编程语言。因为他们有其他的事情要做,不会自己做这样困难的努力。
All this is huge specification and implementation work. For rather light benefits. And worrisome drawbacks.
所有这些都要大量的规范和实现工作。为了非常轻微的益处,带来麻烦的缺点。
Yes, this enables server-side developers to keep control of their URL structure without redirections (today I’ll rename “users/” to “accounts/” — it’s smoother), but at what cost? Unless you constantly generate new URLs to prevent it, I bet your API consumers will hardcode URLs anyway, to avoid this extra layer of complexity (recognition of affordances, URL traversal caching etc.)
是的,这可以让服务端的开发者控制他们的URL的结构,不需要重定向(今天我要把”users/”改名为”accounts/”–这很平滑),但是代价是什么呢?除非你持续地创建新的链接来阻止,我打赌你的API的客户会无论如何采用硬编码URL的方式来避免额外的一层复杂(认识到功能可见性、URL遍历缓存等)。
Yes, this enables the server to control available actions, when the end consumer is a human. But what about User eXperience? The arbitrary showing and masking of affordances by the server is a scary concept. When a “delete” button is missing on a SPA, I want to know why. And if I ask my REST-crawler program to create “this” resource, I’d rather have him fail with a proper remote error message, than say “sorry, couldn’t find the affordance for that.” Actions can be prevented by security rules, missing dependencies, concurrent tasks, and other issues. We have the right to know what’s going on, and “affordances,” in their current form, miss this crucial feature.
是的,当终端用户是人类,这让服务端可以控制现有的行动。但是用户体验如何呢?服务端认为显示和隐藏功能可见性是一个可怕的概念。当一个SPA(Service Provider Application?)的删除按钮不见了时,我想知道原因。如果我让我的REST爬虫程序来创建这个资源,我宁愿它失败并返回合适的远程失败错误消息,也不愿意它说”对不起,不能发现可见资源”。行动可以由安全规则、缺失的依赖、并行的任务和其他原因阻止。我们有权知道实情,然而现在这样的”功能可见性”缺少这样关键的特性。
Also, what about machine-to-machine interactions? If API evolvability is key, how does the consumer program understand new fields and new affordances? Roy Fielding answers “That is where code-on-demand shines.” No way. No way you’re dynamically injecting your remote code into my Python program anytime soon.
那么,机器对机器的交互又如何呢?如果API的发展是关键,那用户程序如何理解新的字段和新的功能可见性呢?Roy Fielding回答说”这是按需编码要解决的”。不可能。短期内不可能你动态地把你远程的代码注入到我的Python程序。
After reading hundreds of pages on the REST/HATEOAS subject, I’ve rarely been so unimpressed. Reaching LEVEL 3 of RESTfulness was supposed to be an epiphany. I rather have the deep feeling that the remedy is worse than the disease.
在读了数百页的REST和HATEOAS主题后,我很少这样无动于衷。达到第三层REST境界只有上帝显灵。我有强烈的感觉药方比疾病还可怕。
Now, some people argue that Roy Fielding is pushing the concept too far, that “lightweight REST” (i.e “Richardson Maturity Level 2,” without Hypermedia Controls) is the real goal to head for.
现在一些人争论Roy Fielding目前在推动的”轻量REST”(就是”Richardson成熟度二级,没有超媒体控制)是真正要朝向的目标。
But still, I bet you actually do not need any of this.
我仍然打赌你不需要任意一层。
You (most probably) do not want code-on-demand. You want your clients to read your specs, and call your API precisely as you (and they) intend it.
你(很大可能)不想要按需编码。你想你的客户读你的规范,以你(和他们)期待的方式精确地调用你的API.
You (most probably) do not want network-level visibility. On the contrary, you want as much TLS encryption as possible.
你(很大可能)不想要网络层的可见性。相反你尽可能地想要TLS(Transport Level Security)加密。
You (most probably) do not want shared caches or client-side caching. On the contrary, remote caches are amongst your worst enemies. And if your API consumers are not browsers, they typically ignore caching headers anyway.
你(很大可能)不想要共享缓存或客户端缓存。相反,远程缓存是你最坏的敌人之一。如果你的API的用户不是浏览器,典型地他们会无论如何忽略缓存头信息。
You (most probably) can do without content negotiation, and other HTTP features more or less bundled with REST best practices (you know, for Representation versus Resource). Every up-to-date language can understand formats like Xml and Json.
你(很大可能)不需要内容协商和其他或多或少随着REST最佳实践而来的其他的HTTP的特性(你知道,因为表示和资源的对立)。每一个新的语言都能够理解像xml或json这样的格式。
You (most probably) do not want to expose Resources for CRUD operations, and use these awkward men-in-the-middle to trigger actual operations in your applications.
你(很大可能)不想为查插删改操作暴露资源,而暴露这些尴尬的中间人来触发你的应用的实际操作。
All you (most probably) want is to expose a bunch of your server-side functionalities to remote browsers or servers. In a quick, elegant, robust, way.
所有你(很大可能)想要的是以快速优雅稳健的方式向远处的浏览器或服务器暴露一大波服务端的功能。
Your API (most probably) screams “RPC”. And in this case, not even a skyscraper-sized shoehorn will allow it to fit into the very ambitious, but rarely relevant, REST Architectural Style.
你的API(很大可能)是基于RPC的。在这种情况,即使是摩天大楼大小的鞋拔子也不能让它适配进有野心的但很少相关的REST架构风格里。
For sure, you might need this or that property of HTTP. For example, you might want to use the GET method and different URIs for your Ajax-originated read-only operations to benefit from browser-side caching. Or you might want to expose your database as CRUD-over-HTTP to leverage generic implementations (like Active Record style clients for JsonAPI protocol).
肯定,你可能需要HTTP的这个那个属性。例如,你可能想为你的AJAX始发的只读的不同操作使用GET操作和不同的链接以利于浏览器端缓存。或者你可能想以利用HTTP的通用的实现来暴露对你的数据库查插删改操作(就像为了JsonAPI协议而实现的Active Record风格的客户端)。
But whatever your needs are, life is short. You do not need to start from an abstract “set of guidelines” like REST constraints. You had better seek a turnkey protocol, matching the needs you really have.
但是不管你的需要是什么,生命短暂。你不需要从一个集合的像REST的限制一样的抽象的指导方针开始。你最好寻找到一个交钥匙的匹配你的真正需求的协议。
There are tons of such solutions (mostly non-RESTful), for lightweight RPC, CRUD, pub/sub, job queues, remote filesystems, data querying/filtering, high performance computing, and bi-directional messaging. Rarely, you’ll have to innovate — add new capabilities to a protocol, or use hybrid approaches. But beginning to “turn verbs into nouns” or following abstract principles as dogmas is the last thing you need to do.
有许多这样的方案(大多数是非REST的),如轻量级的RPC, CRUD,发布/订阅,任务队列,远程文件系统,数据查询/筛选,高性能计算,双向消息。很少你需要革新,往一个协议中加新功能或者是用混杂的方案。但是开始”把动词变为名词”或者遵循抽象的教条的准则是你要避免的。
Please note, by the way, that CRUD can also be done as a mere subset of RPC. Webservices are usually not coded in C language anymore, so if you see one more wanderer arguing that “it’s awful to have to code so many boilerplate CRUD functions”, please enlighten them with this high-technology API.
记住,顺便说一下,CRUD也可以作为RPC的子集来完成。网络服务通常不需要C语言编程,如果你看到一个犹豫者在争论写太多CRUD函数的模板很糟糕,请用高科技的API来启发他们。
create(type, **params) -> id
retrieve(type, id, **params)
update(type, id, **params)
delete(type, id, **params)
Along your (most probably) RESTless way, you’ll meet dozens of adamant speeches, claiming that only REST can grant you scalability and longevity. There is little need to disprove what has never been proven. All I can judge, from personal experience, is that:
在你(很可能)无REST道路上,你会遇到几十场固执的演讲,宣称只有REST可能给你可扩展性和长寿。没必要证伪从没证实的东西。我所能通过个人经验判断的是:
A well configured database and a simple server-side cache are enough for 99% of webservices; an old wisdom says premature optimization is the root of all evil.
一个配置好的数据库和简单的服务端缓存对网络服务来说99%情况都够用;一条旧的箴言说过早的优化是万恶之源.
Services evolve continuously. Whether it means a new parameter in a remote procedure or a new field in a resource representation, it doesn’t matter much. And the API Evolution concept is, as far as I’ve read, nothing but plain old wisdom from software development: don’t make breaking changes until absolutely needed, and use compatibility layers to help everyone move forward at a sane pace.
服务会持续演进.是在一个远程方法上加一个参数还是在资源上加一个域,都没关系.API演进的概念就我理解就是旧的软件开发领域的智慧:除非绝对需要不要做破坏性的改变,使用兼容层来帮助每一个人以健康的节奏前行.
Even if you design your API awkwardly, it will certainly be dead loooong before it has real compatibility issues. Maybe not because its purpose has become irrelevant, and maybe not because of crushing competitors, but likely because of changes-of-mind in your marketing department.
即使你的API设计得笨拙,它遇到兼容问题也需要很长时间.可能不是由于它的目的变得不相干,可能不是由于压倒性的竞争,而是由于你的市场部改变了想法.
With the time spent to properly integrate most REST-style APIs, one could implement several successive versions of corresponding lightweight RPC webservices. Let’s remain pragmatic.
有花在集成REST风格的API上的时间,一个人可能都已经实现了多个后续版本的轻量级RPC网络服务.让我们实际一点.
When a tech startup, with a life expectancy below 2 years, spends one third of its time writing REST(ish) boilerplate, its CTO might deserve to be slapped with a large trout. Good programming practices and cheap workarounds are all they need, until they reach the state where scalability becomes a matter worth thinking about and spending money on.
当一个预期寿命小于2年的初创技术公司花费1/3的时间来写REST样子的模板的时候,应该用一条大的鳟鱼来打它的CTO一个耳光.在他们达到扩展性值得花时间和金钱的状态前,好的编程实践和廉价的变通方案是他们需要的。
Most importantly, please give up this Holy Grail Quest called “HATEOAS,” unless you’re part of the few Knights in the world concerned by this Mission.
更重要的,请放弃对叫做”HATEOAS”的圣杯的追求,除非你是这个世界上少数的被这场使命所关系到的骑士中的一员。
REST/HATEOS is for specific data-centric APIs: those which are naturally CRUD, those which are consumed via ActiveRecord or DataMapper patterns in your favorite languages, those which do not have tons of subtle constraints and side-effects between the fields of a model, and those meant to be explored by humans (currently the only entities in the universe able to understand what this newly appeared “billing contact email” field means).
REST/HATEOS适用于特定的数据为中心的API:那些自然查插删改的API,那些只通过你的最喜欢的语言的ActiveRecord或DataMapper模式来消化的API,那些模型的各个域之间没有很多微妙的限制和副作用的API,还有那些为人类所查看的API(目前在宇宙中只有人类可以理解新增加的”账单联系email”域的含义).
Otherwise, you’ll end up with the awkwardness of RESTish APIs, but with an extra stack of complications.
否则的话,你将会得到笨拙的REST样子的API,还带有额外的复杂性.
When used inadequately, REST is like “Monty Python and the Holy Grail,” but with thousands of rabbits
One relevant use case for HATEOS would be a generic “Database Admin Protocol,” allowing any server to drive a same generic Single Page Application through the structure of its (SQL or no-SQL) database: navigation between tables and record pages, autogenerated forms for each schema, dynamic create/edit/delete buttons, and so on.
当不恰当地使用的时候,REST就像”巨蟒和圣杯”一样,但是还有成千的野兔.一个使用HATEOS的相关的用例是通用的数据库管理协议,允许任意的服务器通过(或者SQL或者非SQL)数据库的结构来驱动相同的单页面应用:在表和记录页之间导航,自动生成每张表的窗体,动态创建,编辑,删除的按钮,等等.
In similar fashion, an API dedicated to browsing and editing documentation, or exploring/pulling/pushing a Version Control System, would lend itself well to a REST architectural style. But these are far, very far, from what most webservices are built for. And if Github switched from REST to GraphQL for its API, it’s a hint that the benefits reclaimed by REST were just not enough.
类似地,浏览或编辑文档的API,或者探索,请求,推送一个版本控制系统的API很适合REST架构风格.但是大多数网络服务都不是做这个用的.如果Github把它的API从REST切换到GraphQL,这是一个暗示,REST名不符实.
Where did it go wrong?
哪里错了?
So here we are. REST/HATEOS is certainly a nicely evolved architectural style, but (imho) only relevant to a tiny fraction of use cases. And now it has spread like cancer over the ecosystem of webservices — mostly under its truncated form called “RESTish APIs” — bringing inadequacy and artificial complexity everywhere.
所以我们在这.REST或HATEOS当然是很好地演进的架构风格,但是(imho,in my humble opinion,恕我直言)只对一小部分的用例是这样的。但是现在它像癌细胞一样在网络服务的生态系统扩散–大多数是以被裁减了的“REST样子的API”的形式–在各处带来不恰当的人为的复杂性。
Who is to blame for this awkward situation?
这个尴尬的境地我们应该怪谁呢?
The original dissertation, which didn’t position REST in comparison to other architectures, and remained too vague on its pros and cons?
怪原始的论文没有把REST和其他架构比较,没有说清它的优点和缺点吗?
The REST advocates, who often lost themselves in very subjective (when not contradicting) recommendations, instead of advertising standards and explaining when (not) to use REST?
怪REST的倡导者吗,他们经常在非常主观的推荐中迷失了自己,而不是宣传标准和解释什么时候使用(或不使用)REST.
The uncountable articles who displayed a false dilemma between SOAP and REST, thus propelling to the stars a winner by default?
怪无数的文章展示了假的SOAP和REST的两难境地,因此非常想在两者中找一个赢家吗?
The Internet trolls who proclaimed, in about every StackOverflow thread regarding webservices design, “Forget existing protocol XYZ, it’s an extra layer which makes stuffs unmaintainable, all you need is handmade HTTP”?
怪网络中的巨魔潜行者在每一个StackOverflow讨论帖子中宣称网络服务的设计”忘掉现有的协议甲乙丙,它是使事情难以维护的另一层,所有你需要的就是手工的HTTP”?
The buzzword lovers who imposed REST to their teams, without discussing the impacts of this architectural change, without ever asking themselves “but why though?”
怪热词爱好者在他们的团队中施加REST,不讨论对架构的改变的影响,不曾问他们自己”为什么”吗?
The silent mass of developers, who, like me, have known FOR YEARS that something was deeply wrong, but haven’t blown the whistle?
怪沉默的大多数开发者吗?他们像我一样有很多年都都觉得某件事是错的,但是也没有吹口哨?
Yup. I guess it’s a mix of all these.
是的.我猜要怪所有这些的混合.
The cruel irony of this story is that the original dissertation itself warned about bandwagon jumping and improper architectural choices:
这个故事的残酷的讽刺是,原始的论文警告了赶时髦和不合适的架构选择:
“How often we see software projects begin with adoption of the latest fad in architectural design, and only later discover whether or not the system requirements call for such an architecture. Design-by-buzzword is a common occurrence. […] The REST interface is designed to be efficient for large-grain hypermedia data transfer, optimizing for the common case of the Web, but resulting in an interface that is not optimal for other forms of architectural interaction.”
“我们经常看到软件项目开始采用新的时髦的架构设计,到后面才去发现这样的架构是否适合需求.基于热词的设计是普遍现象.REST接口被设计为对大粒度的超媒体数据传输有效率,对万维网的常用的用例是优化的,但是也导致它对其他类型的结构交互不是最优的.
Some good news, however, is that REST has paved the way for other protocols, like GraphQL and HTTP2. And its use of advanced HTTP features is an inspiration for other architectures. We owe it at least that.
然而,一些好消息是,REST导致了其他协议的出现,比如GraphQL和HTTP2.它对HTTP高级特性的使用是对其他架构的启示.至少这方面我们归功于它.
What if you really have to RESTify?
如果你必须使用REST的话呢?
For lots of reasons (like corporate hierarchy, or really needing CRUD with HTTP caching), you might have to go for REST. With or without HATEOAS.
有很多原因(比如公司的上层官僚决定的,或者真的需要查插删改操作的HTTP缓存)致使你必须用REST,不管有没有HATEOAS.
In my previous article, I suggested that industrializing REST clients and servers was a problem without solution. It turns out I was wrong.
在我之前的文章中,我表明了工业化方法实现REST客户端和服务端是有问题的没有方案。结果我错了。
Here is an non-exhaustive list of REST-related “standards,” grabbed from the inputs of various commenters. You can find a lot more on Phil Sturgeon’s new standards.rest listing.
这里是不全面的REST相关标准的规范,从各种评论者的输入攫取而来。你能够在Phile Sturgeon的新标准中发现更多REST的列表。
To specify semantics of PATCH: JSON Patch, JSON Merge Patch
指定PATCH的语义: JSON Patch, JSON 合并 Patch.
To specify interface contracts: JSON Schema, API Blueprint, OpenAPI (formerly Swagger), RAML, GraphQL Types, XML Schema
指定接口的协议:JSON大纲,API蓝图,OpenAPI(之前的Swagger),RAML,GraphQL类型,XML大纲。
To serialize results and/or errors in responses: JSend format, RFC7807 (Problem Details for HTTP APIs), Sparse fieldsets (restricting the fields to return), Compound documents (including related resources)
在响应中序列化结果和/或错误:JSend格式,RFC7807(HTTP API的问题细节),稀疏的域集(限制域的返回),复合文档(包含相关资源)。
Protocols with hypermedia controls: JSON Hyper-Schema (IETF Draft), JSON Hypertext Application Language or “HAL” (IETF Draft), Json-API, OData, Mason, Hydra/JSON-LD, JSON SIREN
带超文档控制的协议:JSON超级大纲(IETF草案),JSON超文本应用语言或者“HAL”(IETF草案),JSON-API,OData, Mason, Hydra/JSON-LD, JSON SIREN
These are indeed quite a good number of possibilities. A combinatorial explosion of possibilities, since many of them only take care of a small portion of the protocol. These efforts at standardizing are welcome, although they are somehow late: the most RESTful ones (for hypermedia) are, nearly 18 years after Roy Fielding’s dissertation, still drafts.
这些实际上是很多的可能性。爆炸性的组合的可能性,因为他们中的许多只是关心协议中的一小部分。虽然有些迟,在标准化阶段的这些努力是很好的:最符合REST的规范(对超媒体),在Roy Fielding的论文发表18年后,仍然处于草案阶段。
REST APIs have standards. Like phone chargers do.
REST API有规范。就像电话充电器有规范一样。
Do you know why I didn’t cite any of them in my previous rant?
你知道为什么在我之前的雄辩中我没有引用他们中的任何一个吗?
Because during all those years spent integrating the APIs of big companies (think Google, Microsoft, Oracle, Dropbox, Spotify, and others), as well as that of smaller enterprise, NOT ONCE have I met any of these “standards,” neither explicitly nor implicitly. Maybe it’s because I was unlucky. Maybe it’s because they are rarely used.
因为在这些年在大公司集成API期间(想象Gooble,微软,甲骨文,Dropbox, Spotify和其他公司),包括一些小公司,我没有一次遇到过这些规范,不管是显式的还是隐式的。可能是因为我不幸运。或许是因为他们很少用到。
From my point of view, this lack of visible standardization has to do with the original sin of the REST: for some reason, it came with a very strong anti-standards mindset, with an obscurantist “all you need is love and HTTP” philosophy. So even the most talented developers felt the urge to specify their own half-baked protocol, in their corner, oblivious to thousands of others who had already done the same.
就我来看,没有可见的标准与REST的原罪有关:因为一些原因,它出来时就具有强烈的反标准倾向,具有故弄玄虚性。所有你需要的就是爱和HTTP的哲学。所以,即使是最天才的开发者都有欲望在他们的角落来设计他们自己的半生不熟的协议,对其他的数以千计的已经完成了的相同功能的协议视而不见。
In your case, naturally, the least harm will be to use existing standards and libraries. Preferably full-fledged protocols, rather than LEGO-style assemblies of RFCs.
在你的用例中,自然地最无害的方式就是使用现有的标准和库。尤其是羽翼丰满的协议,而不是像乐高积木一样的RFC规范的集结而已。
I shall warn you, though. Here be dragons, too.
虽然我会警告你。龙也在这里(?)。
Sometimes, the devil is in the details. An old wisdom in computer sciences states that errors shall not go silent. That’s why it’s good practice to keep the format of objects consistent: some of their fields might be nullified, but they are present at all time anyway (unless asked otherwise by the client). That’s the best way to prevent false negatives (due to typos), and to avoid random breakages in strict clients if the quantic property of these fields was (as often) not properly documented.
有时邪恶存在与细节里。计算机科学的传统智慧认为错误不应该悄悄地被隐藏。这就是为什么好的实践要求保持对象的格式的一致:虽然有一些域可以是空的,但是所有时候这些域都应该存在(除非客户要求不这样)。这是阻止假阴性的最好的方式(因为手抖),如果这些域的属性没有很好的文档说明(经常这样),还可以避免随机的要求严格的客户的损坏。
I thought that this idea naturally applied to REST representations, too. Too bad: standards like JSON Merge Patch force you to delete remote fields instead of nullifying them. These tiny but apocalypse-triggering details are especially inappropriate in a philosophy which claims to “help client and server evolve independently.”
我认为这个想法也可以自然地应用到REST的表示上面。太坏了:像JSON合并补丁这样的规范强迫你删除远处的域而不是把他们置空。当一个哲学宣称帮助客户端和服务端互不影响地演进的时候,这些小的但是会导致世界末日的细节是尤其不合时宜的。
Sometimes, the devil is elephant-sized. Ever heard about this OpenAPI (formerly Swagger), one of the most ambitious REST standards? The idea is to describe your API in a specification file, with endpoints and schemas, and use OpenAPI tools to industrialize the creation of both client and server. It sounds nice, doesn’t it?
有时候,恶魔有大象的身材。曾经听说过OpenAPI(之前的Swagger)吗,野心勃勃的REST规范之一?它的想法是用一个规范文件来描述你的API,带有端点(资源)和大纲,然后用OpenAPI工具来工业化客户端和服务端的创建。这听起来很好,不是吗?
Here is an example json interface spec, for the Kubernetes API. Yes, Json schemas are by nature extremely verbose.
这是一个 Kubernetes API的json接口规范的例子。是的,由于Json大纲的本质它非常冗长。
Ok, now here is the corresponding client implementation for Python.
好的,现在是相应的Python的客户端实现。
As of today, it’s more than 90,000 lines of Python code and comments, automatically generated by OpenAPI. Not just thin wrappers, to benefit from auto-documentation tools and IDE autocompletion. 90,000 lines. More than the Json specs. What. the. actual. heck.
到今天,它有超过90000行的Python代码和注释,都是由OpenAPI来自动生成的。不仅是获益于自动文档工具和集成开发环境的薄的一层封装。90000行代码。比Json规范长。真见鬼。
When you ask OpenAPI for a catamaran
当你向一个游艇询问OpenAPI的时候。
Each language, each framework, has its own idea on how to handle OpenAPI. Some choose hybrid (and elegantly cruft-free) approaches. Some generate a spec file from server code. Most generate tons of boilerplate from said spec file. Sometimes they go farther and generate tests, too.
每一个语言,每一种框架,都有它自己的如何处理OpenAPI的想法。一些选择混杂的(优雅地没有令人讨厌的东西)的方法。一些通过服务端的代码来生成规范文件。大多数从所谓的规范文件生成成千上万的模板代码。有时它们更进一步还会生成测试代码。
More tooling and more code generators mean more bugs and harder learning curves… and all that for what? The Kubernetes SDK is exposed to Python as a set of methods. With hardcoded URLs. Again, some RPC-over-CRUD system, considered by many as state-of-the-art RESTfulness, while disregarding HATEOAS. I find all this utterly confusing, and I hope I’m not the only one.
更多的工具和代码意味着更多的缺陷和更难的学习曲线…所有这些为了啥?Kubernetes的SDK暴露给Python的是一个集合的带有硬编码的URL的方法。又一次,一些CRUD系统上的RPC,被许多人认为是REST的现存的艺术杰作,是不管HATEOAS的。我发现所有这些完全使人迷惑,我希望我不是唯一这样的人。
So be especially wary about REST-related protocols and frameworks you might choose. Some are handy and efficient, but some make REST look more and more like the new SOAP.
对你可能选择的REST相关的框架和协议保持高度警觉。一些是方便和高效的,但是一些使REST看起来更像是新的SOAP。
TL;DR
摘要(TL;DR, Too Long, Don’t Read)
The original REST™ is like rocket engineering: exciting, but very specific, quite complex, and rather harmful unless you precisely know what you’re doing.
原始的REST就像火箭工程:令人兴奋,非常特殊,尤其复杂,特别有害除非你精确地知道你在做什么。
RESTish APIs are more affordable, but be sure that you‘ll benefit from them, since it’s rarely the case. To quote a simple rule of thumb from Phil Sturgeon:
REST样的API是更加支付的起的,但是确保你会从中受益,因为这种情况很少发生。引用一些从Phil Sturgeon那里来的行为准则。
“If an API is mostly actions, maybe it should be RPC. If an API is mostly CRUD and is manipulating related data, maybe it should be REST”.
如果一个API主要是行动,也许它应该是基于RPC的。如果一个API主要是CRUD和维护相关的数据,可能它应该是REST的。
Lots of REST(ish) “standards” exist, so no need to ever specify one from scratch. But whatever your needs are, beware of buzzwords, use the right tool for the right job (REST and RPC are only two amongst hundreds), and most importantly, KISS. I bet you’d have more success using a generic JsonAPI client and validating it against a real preprod server, than spending days generating tons of boilerplate OpenAPI code — only to discover later that it doesn’t actually match the remote side because of bugs or other incompatibilities.
许多REST样子的规范存在,所以不必自己从零开始。不管你的需求是啥,小心时髦的热词,用正确的工具做正确的工作(REST和RPC是数百规范中的两个),还有重要的是保持KISS(Keep it Simple and Stupid)原则。我打赌使用一般的JsonAPI客户端用一个真的产品的服务器来验证它,会比你几天的时间生成成吨的模板OpenAPI代码然后发现它因为缺陷和不兼容根本不匹配远端更成功。
The same goes for other architectures, by the way: you’ll probably save time using simple JsonRPC or JsonWSP protocols, instead of generating boilerplate with gRPC, only to later realize that this shiny protocol hasn’t even specified how to report application-level errors.
顺便说一下,这对其他的架构也一样:你使用简单的JsonRPC或JsonWSP(Web Service Protocol)协议,而不是用gRPC来生成模板然后发现这个闪亮的协议竟然都没有指定如何汇报服务端的错误,可能更节省时间。
Epilogue
结束语
REST is a difficult subject to talk about. There are lots of plot holes in the founding dissertation, lots of conflicting definitions, lots of contradicting opinions on how to do this or that right, lots of unjustified hypes and disgraces, lots of (underused and partial) standards… and very few real life examples of HATEOAS APIs (most links I’ve crossed were dead, so much for the “lasting decades”).
REST是很难谈论的一个话题。在最初的论文中有很多情节漏洞,许多冲突的定义,许多矛盾的如何做这做那的矛盾的观点,许多不当的大肆宣传和强调,许多的(很少使用的不全面的)规范…和很少的真实世界的HATEOAS API的案例(我碰到的许多链接都是死链接,以后少说”持续数十年“)。
But I hope that this analysis has clarified a bit the different “RESTs” people are talking about, and that it will spare you some of the obscene amount of time I had to spend just to somehow understand what the Original REST™ was meant to be.
但是我希望这个分析已经澄清了一些人们讨论的不同的REST,可以节省你们像我一样花费很多令人憎恶的时间在无论如何理解原始的REST的意图上面。
At the very least, you now have a new weapon in your bag. The next time your boss wants you to expose some server operations as REST webservices, just ask:
至少在你的包包里边有一个新的武器了。下一次你的老板想你暴露一些服务端的REST网络服务的时候,就问:
For this API, do we really need to follow a composite architectural style meant for Internet-scale distributed hypermedia systems?
为了这个API,我们真的需要遵循一个组合式的为了互联网规模的分布式超媒体系统设计的架构风格吗?
The expression on his face will be your answer.
他脸上的表情就是你的答案。