by Sanchit Gera
通過Sanchit Gera
RESTful服務的第三部分:HATEOAS和Richardson成熟度模型 (RESTful Services Part III : HATEOAS and The Richardson Maturity Model)
In Part I of this series, you learned the very basics of HTTP. We went over common HTTP constructs such as headers, URLs and the different status codes available. We also looked at how each of these constructs could be useful when building resource-oriented web services.
在本系列的第一部分中,您學習了HTTP的基礎知識。 我們介紹了常見的HTTP結構,例如標頭,URL和可用的不同狀態代碼。 我們還研究了在構建面向資源的Web服務時這些構造中的每個構造如何有用。
In Part II, you learned about the different constraints you need to comply with in order to build scalable, high-performance RESTful systems.
在第二部分中 ,您了解了為了構建可擴展的高性能RESTful系統需要遵守的各種約束。
This post will provide you with the third and final piece of the puzzle. As noted before, REST is not a standard, but rather an abstract concept. This makes it hard to quantify exactly how “RESTful” a service is or isn’t.
這篇文章將為您提供難題的第三篇也是最后一部分。 如前所述,REST不是標準,而是抽象概念。 這使得很難準確地量化服務是否是“ RESTful”的。
While the constraints discussed in the previous part are helpful when creating a service, they aren’t as good at solving this problem. What if you chose to follow exactly one of those constraints? Two? Three? At what point does your service stop being partially RESTful and cross over into the magical land of complete RESTful-ness?
雖然上一部分中討論的約束在創建服務時很有用,但它們并不能很好地解決此問題。 如果您選擇完全遵循這些約束之一怎么辦? 二? 三? 在什么時候,您的服務會停止部分地成為 RESTful并跨入完全 RESTful-ness的魔境?
This is exactly the problem that the Richardson Maturity Model (RMM) helps you solve. But before we dive further into the nitty gritty of RMM, there’s one final topic that will prove to be useful in your understanding of REST.
這正是Richardson成熟度模型(RMM)可以幫助您解決的問題。 但是,在我們進一步深入研究RMM的本質之前,有一個最后的主題對您理解REST很有用。
HATEOAS原理 (The Principle of HATEOAS)
Hypermedia As The Engine Of Application State, shortened to HATEOAS, builds on one of the constraints of REST (the Uniform Interface). I am still trying to determine how to pronounce it. I usually alternate between Hate-ee-ose and Hate-ose. Feel free to choose either, or come up with your own. But anyway, I digress.
?ypermedia 甲 式T他?ngine?F A pplication 小號泰特,縮短到HATEOAS,建立在REST的約束中的一個( 統一的接口 )。 我仍在嘗試確定如何發音。 我通常會在“討厭的人”和“討厭的人”之間切換。 隨意選擇,或者提出自己的想法。 但是無論如何,我離題了。
The overarching goal behind HATEOAS is to provide a consistent way for machines to understand APIs and navigate them without having any information about them beforehand, identical to a user visiting a website for the first time.
HATEOAS的總體目標是為機器提供一致的方式來理解API和瀏覽API,而無需事先獲得有關API的任何信息,這與首次訪問網站的用戶相同。
Assume you were visiting Medium for the first time to write a post. What steps would you take? In all likelihood, you would visit Medium’s homepage, head over to the Stories section, and begin writing your masterpiece. You aren’t really concerned with the URL that Stories section lives on. You don’t have it memorized, but you know that you will be able to get there when you need to.
假設您是第一次訪問Medium寫一篇文章。 您將采取什么步驟? 您很可能會訪問Medium的主頁,轉到“ 故事”部分,然后開始撰寫您的杰作。 您實際上并不關心“ 故事”部分所依據的URL。 您沒有記住它,但是您知道您將可以在需要時到達那里。
Or imagine you were ordering something on Amazon. You go in, search for different items, add them to the cart, and checkout. The location of each of these components within the system is inconsequential to you as a user. If the URL required to get to the cart, there is a strong chance you wouldn’t even find out. And yet, your experience remains unhampered.
或想象您正在亞馬遜上訂購商品。 您進去,搜索其他項目,將它們添加到購物車,然后結帳。 這些組件中每個組件在系統中的位置對于您來說都是無關緊要的。 如果需要購物車的網址,很有可能您根本找不到。 但是,您的經驗仍然沒有受到阻礙。
In both cases, you only need a single piece of information, that is the entry point to the website. Everything else from that point on is completely discoverable and usable by navigating relevant links (aka hypermedia). This is how the web is designed to work and indeed how most users experience it today.
在這兩種情況下,您只需要一條信息,即網站的入口點。 從那時起,通過導航相關鏈接(也稱為超媒體) ,可以完全發現并使用所有其他內容。 這就是設計網絡工作方式的方式,實際上也是當今大多數用戶的體驗方式。
HATEOAS extends this idea of discoverability to APIs and web services as well. What if, given a single point of access to the service, I could make use of everything that it has to offer? Luckily, this can be achieved by exploiting the resource oriented nature of our data that we have been working so hard on!
HATEOAS還將可發現性的思想擴展到了API和Web服務。 如果在單點訪問服務的情況下,我可以利用其所提供的一切,該怎么辦? 幸運的是,這可以通過利用我們一直在努力的數據的面向資源的本質來實現!
We know that since everything being returned by our service is essentially a resource, there are only a handful of things that our service consumer can do with that resource. Further, each action corresponds to a well defined RESTful route within our system (think GET, POST, PUT etc.). This means that we could easily embed all potential interactions with a given resource in the form of actionable URLs within the response. Let’s see an example!
我們知道,由于我們的服務所返回的所有內容本質上都是一種資源,因此,我們的服務使用者只能使用該資源做一些事情。 此外,每個動作都對應于我們系統中定義良好的RESTful路由(請考慮GET,POST,PUT等)。 這意味著我們可以輕松地在響應中以可操作的URL形式嵌入與給定資源的所有潛在交互。 讓我們來看一個例子!
Let’s return to our previous example of writing a story on Medium. Imagine if instead of a user-facing website, it was instead purely a web service. Under the HATEOAS model, the only piece of information to navigate the service I need would be the hostname: medium.com
讓我們回到前面的例子中,該故事在Medium上寫。 想象一下,如果它不是面向用戶的網站,而是純粹的Web服務。 在HATEOAS模型下,導航我需要的服務的唯一信息就是主機名: medium.com
I begin my interaction by making a GET request to the host. Medium promptly responds with a list of all the resources it has to offer, along with where I can find them.
我通過向主機發出GET請求開始交互。 中型會Swift響應并列出所有它必須提供的資源,以及在哪里可以找到它們。
GET medium.com
links : [ { rel : "bookmarks", href : "/bookmarks" }, { rel : "stories", href: "/stories" }]
In this simplified version of Medium, I’m told that there are two resources being offered: stories and bookmarks. I’m also told where each of those resources lives on the system.
在此簡化版的Medium中,我被告知提供了兩種資源: 故事和書簽。 還告訴我這些資源中的每一個在系統上的位置。
Next, I need to figure out how to create a new story. From our previous discussions, I already know that this is going to be a POST request, but as a client I still don’t know what kind of data the service is expecting for this request. This is exactly where an OPTIONS request comes in handy. So lets do just that!
接下來,我需要弄清楚如何創建一個新故事。 從前面的討論中,我已經知道這將是一個POST請求,但是作為客戶端,我仍然不知道該服務期望該請求使用哪種數據。 這正是OPTIONS請求派上用場的地方。 因此,讓我們做到這一點!
OPTIONS medium.com/stories
Allow GET, POST{ name : "Stories", description: "Ideas and opinions from around the world", actions: [ { POST: { title: "string", body: "string" } } ]}
Aha! Looks like we need parameters named title and body corresponding to our new post. This gives us all the information that we need. We can now go ahead and start POSTing to the service and creating new articles on the service.
啊哈! 看起來我們需要與我們的新帖子相對應的名為title和body的參數。 這為我們提供了所需的所有信息。 現在,我們可以開始發布服務,并在服務上創建新文章。
Now let’s say that following this approach, I land on an existing story. What would an individual story look like?
現在讓我們說,按照這種方法,我著眼于一個已有的故事。 個人故事會是什么樣?
GET medium.com/stories/3
{ "id": 3, "title": "An Introduction to Microservices", "body": "...", "created_at": "2016-10-25T20:52:12.804Z", "links": [ { "rel": "self", "href": "/stories/1" }, { "rel": "author", "href": "/authors/3" }, { "rel": "comments", "href": "/stories/3/comments" }],}
Now I not only have information about the story, but I also have a means of getting information about the author and the comments.
現在,我不僅可以獲得有關故事的信息,而且還可以獲取有關作者和評論的信息。
Of course, this is overly simplistic. There are tons of other things going on such as authentication and authorization that need to be taken care of. And a lot of work needs to be done to design systems that are decomposable into resources this easily. But it serves well to understand the idea behind HATEOAS.
當然,這過于簡單了。 還有很多其他事情需要進行,例如身份驗證和授權。 要設計可輕松分解為資源的系統,需要做大量的工作。 但是,了解HATEOAS背后的想法非常有用。
This eliminates the need for you as a developer to maintain documentation for your service. Everything a client could possibly need to know about using your service is already in there.
這消除了您作為開發人員維護服務文檔的需要。 客戶可能需要知道的有關使用您的服務的所有信息。
Similarly, as a client, I do not need to keep track of the URLs associated with each of these resources. I look for the object corresponding to the resource, and navigate to it. If it changes, I don’t care.
同樣,作為客戶端,我不需要跟蹤與這些資源中的每一個相關的URL。 我尋找與資源相對應的對象,然后導航到它。 如果改變了,我不在乎。
With this in mind, let’s now shift our focus to the Richardson Maturity Model (RMM).
考慮到這一點,現在讓我們將重點轉移到Richardson成熟度模型(RMM)。
理查森成熟度模型 (The Richardson Maturity Model)
As mentioned previously, RMM is a tool to help you evaluate how RESTful a service is. This system of classification — first described by Leonard Richardson — provides a neat way to think about your web services from the perspective of an end user, then make judgments accordingly.
如前所述,RMM是幫助您評估服務的RESTful程度的工具。 這種分類系統(首先由Leonard Richardson描述)提供了一種從最終用戶的角度考慮Web服務并進行相應判斷的巧妙方法。
Richardson describes four distinct levels in the spectrum of RESTful-ness.
理查森(Richardson)描述了RESTful-ness范圍中的四個不同級別。
0級 (Level 0)
This is rock bottom when it comes to a service being RESTful. Services in this category follow the “one URL, one method” principle. That means, the service only exposes a single URL to the outside world and accepts only one type of request (usually POST) at that location.
當涉及到RESTful服務時,這是最基本的。 此類服務遵循“一個URL,一種方法”的原則。 這意味著該服務僅向外界公開一個URL,并且在該位置僅接受一種類型的請求(通常為POST)。
This is typical for SOAP services for example. A typical request to a SOAP service looks something like this:
例如,這對于SOAP服務是典型的。 對SOAP服務的典型請求如下所示:
POST /Quotation HTTP/1.0Host: www.xyz.orgContent-Type: text/xml; charset=utf-8Content-Length: nnn<?xml version="1.0"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle="http://www.w3.org/2001/12/soap-encoding" > <SOAP-ENV:Body xmlns:m="http://www.xyz.org/quotations" > <m:GetQuotation> <m:QuotationsName>MiscroSoft</m:QuotationsName> </m:GetQuotation> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Everything is described in the body of the request, including the action (getQuotation) and the parameters for that request (Microsoft). Clearly, the service does not make use of any of the REST principles we have discussed thus far, not to mention the cost of having a whole other additional data format on top of HTTP.
在請求的主體中描述了所有內容,包括操作(getQuotation)和該請求的參數(Microsoft)。 顯然,該服務未利用我們到目前為止討論的任何REST原理,更不用說在HTTP之上具有其他所有附加數據格式的成本。
級別1:資源 (Level 1: Resources)
The next step on our path to complete RESTful-ness is introducing resources based abstractions. This is the equivalent of breaking up the application into distinct resource specific URLs. It’s characterized by Richardson as the “Multiple URLs, One Method” implementation.
完成RESTful-ness的下一步是引入基于資源的抽象。 這相當于將應用程序分解為不同的資源特定的URL。 理查森(Richardson)將其稱為“多個URL,一種方法”實施。
Here, there are several different URLs in the system working together to provide the desired functionality. But each accepts only one type of requests (again, usually POST).
在這里,系統中有幾個不同的URL協同工作以提供所需的功能。 但是每個都只接受一種類型的請求(同樣,通常是POST)。
So for example, continuing our previous example, we can proceed to first retrieve a list of all companies from our application:
因此,例如,繼續前面的示例,我們可以首先從應用程序中檢索所有公司的列表:
POST /companies[ { "name" : "Microsoft", "id" : 3 }, { "name" : "Apple", "id" : 4 }]
…and then get a quotation for a single company:
…然后獲得一家公司的報價:
POST /quotations/3
{ quotation: {}}
This is definitely a step up from before. In fact, this is how a lot of applications had been written until REST gained popularity. But again, we aren’t utilizing the strengths of HTTP. We can do better!
這絕對是從前的一步。 實際上,這就是在REST流行之前編寫許多應用程序的方式。 但同樣,我們沒有利用HTTP的優勢。 我們可以做得更好!
2級:動詞 (Level 2: Verbs)
Now we throw the concept of action verbs into the mix. In addition to having well defined resources, the actions that can be performed on a resource must strictly follow HTTP conventions.
現在,我們將動作動詞的概念混入其中。 除了擁有定義明確的資源外,可對資源執行的操作還必須嚴格遵循HTTP約定。
A GET MUST not modify the resource state, a POST MUST only be used for resource creation, and so on. It is characterized as, of course, the “Many URLs, Many Actions” system.
GET絕不能修改資源狀態,POST只能用于資源創建,依此類推。 它的特征當然是“許多URL,許多操作”系統。
This brings us to the services most of us are familiar with and use on a day to day basis. These are also the kind of services that we usually consider RESTful. However, there is one more level that services must conform to in order to achieve the coveted status of complete RESTfulness.
這使我們獲得了我們大多數人每天都熟悉和使用的服務。 這些也是我們通常認為是RESTful的服務。 但是,服務必須達到一個更高的級別,才能達到令人羨慕的完全RESTful狀態。
第3級:HATEOAS (Level 3: HATEOAS)
This is where most services fall short. The vast majority of APIs and web services that you encounter as a developer, or likely ones that you will work on likely don’t follow the principle of HATEOAS.
這是大多數服務不足的地方。 作為開發人員或您將要使用的開發人員遇到的絕大多數API和Web服務可能都不遵循HATEOAS的原理。
Most service providers still prefer to document their services traditionally, by providing developers with a list of available endpoints along with some information on how to interact with that endpoint. Here’s the Twitter REST API, for example. (Interestingly, the PayPal API strongly pushes for Hypermedia Controls.)
大多數服務提供商仍然喜歡通過傳統方式記錄其服務,方法是為開發人員提供可用端點的列表以及有關如何與該端點進行交互的一些信息。 例如,這是Twitter REST API 。 (有趣的是,PayPal API 強烈推動了超媒體控件。)
This isn’t necessarily bad. There are some good arguments to be made both in favor of and against utilizing HATEOAS. While on the one hand it makes APIs easy to discover and use, that usually comes at the cost of more development time and effort.
這不一定是壞事。 無論是贊成還是反對利用HATEOAS,都有一些很好的論據。 一方面,它使API易于發現和使用,但通常以花費更多的開發時間和精力為代價。
In fact, if all you need to do is make a single call to the API, introducing HATEOAS may actually make things more difficult for you as a consumer.
實際上,如果您需要做的只是對API的一次調用,那么引入HATEOAS可能實際上會使您作為消費者變得更加困難。
結論 (Conclusion)
At the end of the day, these measures aren’t something you need to be swear by. REST, along with all it’s constraints, is merely a tool in your tool belt when building web services and applications. It’s entirely up to you to take from it what best fits your needs.
歸根結底,這些措施并不是您需要保證的。 REST及其所有約束條件,在構建Web服務和應用程序時只是工具帶中的工具。 完全取決于您的需求,這完全取決于您。
I hope you learned a lot of useful concepts from this series. If you’re looking to create a RESTful web service to supplement your next project, or looking to work with an existing one, you should now have a good understanding of some of the rationales behind them.
希望您從本系列中學到了許多有用的概念。 如果您希望創建一個RESTful Web服務來補充您的下一個項目,或者希望與現有的項目一起使用,那么您現在應該對它們背后的一些原理有很好的了解。
Here are the links to the previous parts, in case you missed them:
如果您錯過了它們,以下是前幾部分的鏈接:
RESTful Services Part I: HTTP in a Nutshell
RESTful服務的第一部分:簡而言之的HTTP
RESTful Services Part II: Constraints and Goals
RESTful服務第二部分:約束和目標
Let me know what you thought of this post in the comments, or contact me via LinkedIn.
在評論中讓我知道您對此帖子的看法,或者通過LinkedIn與我聯系。
Don’t forget to hit the ? if you enjoyed this article.
別忘了打嗎? 如果您喜歡這篇文章。
Cheers and happy learning!
祝您學習愉快!
More Resources
更多資源
Martin Fowler’s Blog
馬丁·福勒的博客
Leonard Richardson’s presentation
倫納德·理查森(Leonard Richardson)的演講
SOAP example borrowed from TutorialsPoint
從TutorialsPoint借用的SOAP示例
翻譯自: https://www.freecodecamp.org/news/restful-services-part-iii-hateoas-and-the-richardson-maturity-model-48d4e4c79b8d/