新聞中心
要點(diǎn)

雜多ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
HATEOAS是Hypertext As The Engine Of Application State的縮寫。在 Richardson Maturity Model中, 它是REST的***級(jí)形態(tài)。
單頁(yè)應(yīng)用正越來(lái)越受到歡迎,前后端分離的開發(fā)模式進(jìn)一步細(xì)化了分工,但同時(shí)也引入了不少重復(fù)的工作,例如一些業(yè)務(wù)規(guī)則在后端必須實(shí)現(xiàn)的情況下,前端也需要再實(shí)現(xiàn)一遍以獲得更好的用戶體驗(yàn)。HATEOAS雖然不是唯一消除這些重復(fù)的方法,但作為一種架構(gòu)原則,它更容易讓團(tuán)隊(duì)找到消除重復(fù)的“套路”。
什么是HATOEAS
HATEOAS是Hypertext As The Engine Of Application State的縮寫。采用Hypermedia的API在響應(yīng)(response)中除了返回資源(resource)本身外,還會(huì)額外返回一組Link。 這組Link描述了對(duì)于該資源,消費(fèi)者(consumer)接下來(lái)可以做什么以及怎么做。
舉例來(lái)說(shuō),假設(shè)向API發(fā)起一次get請(qǐng)求,獲取指定訂單的資源表述(representation),那么它應(yīng)該長(zhǎng)得像這樣:
- HTTP/1.1 200 OK
- Server: Apache-Coyote/1.1
- Content-Type: application/hal+json;charset=UTF-8
- Transfer-Encoding: chunked
- Date: Fri, 05 Jun 2015 02:54:57 GMT
- {
- "tracking_id": "123456",
- "status": "WAIT_PAYMENT",
- "items": [
- {
- "name": "potato",
- "quantity": 1
- }
- ],
- "_Links": {
- "self": {
- "href": "http://localhost:57900/orders/123456"
- },
- "cancel": {
- "href": "http://localhost:57900/orders/123456"
- },
- "payment": {
- "href": "http://localhost:57900/orders/123456/payments"
- }
- }
- }
- 理解Link中的“self”的消費(fèi)者知道使用get方法訪問(wèn)其“href”的uri可以查看該訂單的詳細(xì)信息。
- 理解Link中的“cancel”的消費(fèi)者知道使用delete方法訪問(wèn)其“href”的uri可以取消該訂單。
- 理解Link中的“payment”的消費(fèi)者知道使用post方法訪問(wèn)其“href”的uri可以為該訂單付款。
REST是目前業(yè)界相當(dāng)火熱的術(shù)語(yǔ),似乎發(fā)布的API不帶個(gè)REST前綴,你都不好意思和別人打招呼了。 然而大部分號(hào)稱REST的API實(shí)際上并沒(méi)有達(dá)到Richardson成熟度模型的第三個(gè)級(jí)別:Hypermedia。 而REST的***Roy Fielding博士更是直言HATEOAS是REST的前提, 這不是一個(gè)可選項(xiàng),如果沒(méi)有Hypermedia,那就不是REST。(摘自Infoq對(duì)Fielding博士的第二段訪談)
那么HATOEAS帶來(lái)了什么優(yōu)勢(shì)?
一個(gè)顯而易見(jiàn)的好處是,只要客戶端總是使用Link Rel來(lái)獲取URI,那么服務(wù)端可以在不破壞客戶端實(shí)現(xiàn)的情況下實(shí)現(xiàn)URI的修改,從而進(jìn)一步解耦客戶端和服務(wù)端。
另一個(gè)容易被忽視的優(yōu)勢(shì)是它可以幫助客戶端開發(fā)者探索API,Links實(shí)際上提示了開發(fā)者接下來(lái)可以進(jìn)行何種業(yè)務(wù)操作,開發(fā)者雖然精通技術(shù),但往往對(duì)于業(yè)務(wù)不甚了解,這些提示可以幫助他們理解業(yè)務(wù),至少是一個(gè)查詢API文檔的好起點(diǎn)。想象一下,如果某個(gè)API的響應(yīng)中多了一個(gè)新的Link,敏感的開發(fā)者可能就會(huì)詢問(wèn)這個(gè)Link是用來(lái)做什么的,是一個(gè)新的特性嗎?雖然看起不起眼,但這往往使兩個(gè)團(tuán)隊(duì)的成員溝通起來(lái)更容易。
單頁(yè)應(yīng)用和HATEOAS
在過(guò)去的幾年里,WEB開發(fā)技術(shù)發(fā)生了很多重大的變革,其中之一就是單頁(yè)應(yīng)用,它們往往能帶來(lái)更平滑的用戶體驗(yàn)。在這一領(lǐng)域,分工進(jìn)一步細(xì)化,前端工程師專精客戶端程序構(gòu)建和HTML、CSS等效果的開發(fā),后端工程師則更偏重高并發(fā)、DevOps等技能,大部分特性需要前后端工程師配合完成。
或許有人會(huì)質(zhì)疑,為什么不是全棧工程師?誠(chéng)然,如果一個(gè)人就能端到端的交付特性,那自然會(huì)減少溝通成本,但全棧工程師可不好找,細(xì)化分工才能適應(yīng)規(guī)模化的開發(fā)模式。繼Ajax之后,單頁(yè)應(yīng)用和前后端分離架構(gòu)進(jìn)一步催生了大量的API,我們急需一些方法來(lái)管理這些API的開發(fā)和演進(jìn),而HATEOAS應(yīng)該在此占有一席之地。
在摸索中前進(jìn),自由地重命名你的資源
我們常說(shuō)在敏捷開發(fā)中,應(yīng)該擁抱變化。所以敏捷開發(fā)中推崇重構(gòu)、單元測(cè)試、持續(xù)集成等技術(shù),因?yàn)樗鼈兛梢允棺兓菀住⒏踩?。HATOEAS也是這樣一種技術(shù)。想象一下,在項(xiàng)目初始階段,團(tuán)隊(duì)對(duì)業(yè)務(wù)的理解還不深入,很有可能會(huì)得出錯(cuò)誤的業(yè)務(wù)術(shù)語(yǔ)命名,或者業(yè)務(wù)對(duì)象的建模也不完全合適。反映在API上,可能你希望能夠修正API的URI,在非HATOEAS的項(xiàng)目中,由于URI是在客戶端硬編碼的,即使你把它們?cè)O(shè)計(jì)的非常漂亮(準(zhǔn)確的HTTP動(dòng)詞,以復(fù)數(shù)命名的資源,禁止使用動(dòng)詞等等),也不能幫助你更容易地修改它們,因?yàn)槟愕闹貥?gòu)需要前端開發(fā)者的配合,而他/她不得不停下手頭的其他工作。
但在采用了HATEOAS的項(xiàng)目中,這很容易,因?yàn)榭蛻舳耸峭ㄟ^(guò)Link來(lái)查找API的URI,所以你可以在不破壞API Scheme的情況下修改它的URI。當(dāng)然,你不可能保證所有API的URI都是通過(guò)Link來(lái)獲取的,你需要安排一些Root Resource,例如 /api/currentLoggedInUser,否則客戶端沒(méi)有辦法發(fā)起***次請(qǐng)求。
- HTTP/1.1 200 OK
- Path: /api/currentLoggedInser (1)
- {
- …… //omitted content
- "_Links": { (2)
- "searchUserStories": {
- "href": "http://localhost:8080/userStories/search{?page, size}"
- },
- "searchUsers": {
- "href": "http://localhost:8080/users/search{?page, size, username}"
- },
- "logout": {
- "href": "http://localhost:8080/logout"
- }
- }
- }
- Root Resource,它們是API的入口,客戶端通過(guò)他們?yōu)g覽當(dāng)前用戶有哪些資源可以訪問(wèn),你可以定義多個(gè)Root Resource,并確保它們的URI不會(huì)改變
- Link引入的URI可以自由地變化,可能是因?yàn)樾枰孛Y源,也可能是需要抽取出新的服務(wù)(域名變化)
消除重復(fù)的業(yè)務(wù)規(guī)則校驗(yàn)實(shí)現(xiàn),更容易得適應(yīng)變化
經(jīng)驗(yàn)告訴我們,不能相信客戶端的請(qǐng)求,所以在服務(wù)端我們需要根據(jù)業(yè)務(wù)規(guī)則校驗(yàn)當(dāng)前的請(qǐng)求是否合法。這樣確保了業(yè)務(wù)正確,但當(dāng)用戶發(fā)起了請(qǐng)求后才告訴他們請(qǐng)求失敗,有時(shí)候是一件令人沮喪的事情。為了用戶體驗(yàn),可能會(huì)要求某些組件根據(jù)業(yè)務(wù)規(guī)則展示。例如,對(duì)于某個(gè)業(yè)務(wù)對(duì)象,要求編輯按鈕只在當(dāng)前用戶可以編輯的情況下才展示。在傳統(tǒng)的服務(wù)端渲染架構(gòu)下,一般都可以復(fù)用校驗(yàn)的代碼,而在單頁(yè)應(yīng)用中,往往由于技術(shù)棧不同,代碼無(wú)法直接共用,業(yè)務(wù)規(guī)則在前后端都分別實(shí)現(xiàn)了一次。例如,在我們最近的一次項(xiàng)目中,前后端分別實(shí)現(xiàn)了如下規(guī)則:
- 給定一個(gè)用戶故事
- 只有它的作者才能編輯它
服務(wù)端通過(guò)在用戶故事的API中暴露作者幫助前端完成編輯按鈕的有條件渲染。
- HTTP/1.1 200 OK
- Path: /api/userStories/123
- {
- "author": "[email protected]" (1)
- }
1. 與當(dāng)前用戶比較判斷是否渲染編輯按鈕
但如果規(guī)則發(fā)生變化,前后端都需要適應(yīng)這一改變,所以我們用HATEOAS重構(gòu)了一下:
- HTTP/1.1 200 OK
- Path: /api/userStories/123
- {
- "author": "[email protected]",
- "_links": {
- "updateUserStory": {
- "href": "http://localhost:8080/api/userStories/123" (1)
- }
- }
- }
2. 現(xiàn)在前端會(huì)根據(jù) updateUserStory link是否出現(xiàn)來(lái)驗(yàn)證當(dāng)前用戶是否具有編輯用戶故事的能力
后來(lái)業(yè)務(wù)規(guī)則變?yōu)槌俗髡咧?,系統(tǒng)管理員也可以編輯用戶故事,這時(shí)候只需要后端去響應(yīng)這個(gè)變化就行了。你可能會(huì)質(zhì)疑,通過(guò)為用戶故事暴露一個(gè) isCurrentLoggedInUserAvailableToUpdate的計(jì)算屬性也可以做到。沒(méi)錯(cuò),HATOEAS并不是唯一的辦法,但作為一種架構(gòu)約束,團(tuán)隊(duì)會(huì)自然而然地想到它,而計(jì)算屬性則要求團(tuán)隊(duì)成員有更強(qiáng)的抽象技能。
總結(jié)
HATEOAS提倡在響應(yīng)返回Link來(lái)提示對(duì)該資源接下來(lái)的操作。這種方式解耦了服務(wù)端URI,也可以讓客戶端開發(fā)者更容易地探索API。***,通過(guò)Link來(lái)判斷業(yè)務(wù)狀態(tài),還能有效地消除單頁(yè)應(yīng)用中的業(yè)務(wù)規(guī)則重復(fù)實(shí)現(xiàn)。
【本文是專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】
戳這里,看該作者更多好文
分享名稱:?jiǎn)雾?yè)應(yīng)用的HATEOAS實(shí)戰(zhàn)
鏈接URL:http://fisionsoft.com.cn/article/dpdeoep.html


咨詢
建站咨詢
