如何給老婆解釋什么是Restful

老婆經常喜歡翻看我訂閱的技術雜志,她總能從她的視角提出很多有趣的問題。

一個悠閑的周日下午,她午覺醒來,又習慣性的抓起這個月的雜志,饒有興趣地看了起來。

果不其然,看著看著,她又對我發難了,“Restful是什么呀,老公?是restaurant的形容詞嗎,突然就覺得好餓了啊......”

作為一個合格的程序員,我一直把能夠將一項技術講給老婆聽,并且能給她講懂,作為我已經掌握了這項技術的標準。
如果我直接回答說,“REST就是Representational State Transfer的縮寫呀,翻譯為中文就是‘表述性狀態轉移’”,那她今晚肯定得罰我跪鍵盤。我必須找個合適的機會,把Restful的來龍去脈給她形象的描述一遍。

“走,咱們去樓下咖啡廳吃個下午茶吧”,我對老婆說。

“一個芝士蛋糕,一杯拿鐵,兩條吸管,謝謝”,我對前臺的服務員說,然后我們找了個角落坐了下來。

Level 0 - 面向前臺

“剛才我們向前臺點了一杯拿鐵,這個過程可以用這段文字來描述”,說著,我在紙上寫下了這段JSON,雖然她不知道什么叫JSON,但理解這段文字對于英語專業8級的她,實在再簡單不過。

{
    "addOrder": {
        "orderName": "latte"
    }
}

“我們通過這段文字,告訴前臺,新增一筆訂單,訂單是一杯拿鐵咖啡”,接著,前臺給我們返回這么一串回復:

{
    "orderId": "123456"
}

“訂單ID?還是訂單編號?”
“恩恩,就是訂單編號”
“那我們就等著前臺喊‘訂單123456的客戶可以取餐了’,然后就可以開吃了!”
“哈哈,你真聰明,不過,在這之前,假設我們有一張會員卡,我們想查詢一下這張會員卡的余額,這時候,要向前臺發起另一個詢問”,我繼續在紙上寫著:

"queryBalance": {
        "cardId": "886333"
    }
}

“查詢卡號為886333的卡的余額?”
“真棒!接著,查詢的結果返回來了”

{
    "balance": "0"
}

“切,沒錢......”
“哈哈,沒錢,現在我們要跟前臺說,這杯咖啡不要了”,我在紙上寫到:

{
    "deleteOrder": {
        "orderId": "123456"
    }
}

“哼,這就把訂單取消啦?”

Level 1 - 面向資源

“現在這家咖啡店越做越大,來喝咖啡的人越來越多,單靠前臺顯然是不行的,店主決定進行分工,每個資源都有專人負責,我們可以直接面向資源操作。”
"面向資源?”
“是的,比如還是下單,請求的內容不變,但是我們多了一條消息”,我在紙上畫出這次的模型:

/orders

{
    "addOrder": {
        "orderName": "latte"
    }
}

“多了一個斜杠和orders?這是什么意思?”
“這個表示我們這個請求是發給哪個資源的,訂單是一種資源,我們可以理解為是咖啡廳專門管理訂單的人,他可以幫我們處理所有有關訂單的操作,包括新增訂單、修改訂單、取消訂單等操作”
“Soga...”
“接著還是會返回訂單的編號給我們”

{
    "orderId": "123456"
}

“下面,我們還是要查詢會員卡余額,這次請求的資源變成了cards”

/cards

{
    "queryBalance": {
        "cardId": "886333"
    }
}

“接下來是取消訂單”
“這個我會”,說著,她搶走我手上的筆,在紙上寫了起來:

/orders

{
    "deleteOrder": {
        "orderId": "123456"
    }
}

Level2 - 打上標簽

“接下來,店主還想繼續優化他的咖啡廳的服務流程,他發現負責處理訂單的員工,每次都要去訂單內容里面看是新增訂單還是刪除訂單,還是其他的什么操作,十分不方便,于是規定,所有新增資源的請求,都在請求上面寫上大大的‘POST’,表示這是一筆新增資源的請求”

“其他種類的請求,比如查詢類的,用‘GET’表示,刪除類的,用‘DELETE’表示”

“還有修改類的,修改分為兩種,第一種,如果這個修改,無論發送多少次,最后一次修改后的資源,總是和第一次修改后的一樣,比如將拿鐵改為貓屎,那么用‘PUT’表示;第二種,如果這個修改,每次修改都會讓這個資源和前一次的不一樣,比如是加一杯咖啡,那么這種請求用‘PATCH’或者‘POST’表示”,一口氣講了這么多,發現她有點似懂非懂。

“來,我們再來重復上面那個過程,來一杯拿鐵”,我邊說邊畫著:

POST /orders

{
    "orderName": "latte"
}

"請求的內容簡潔多啦,不用告訴店員是addOrder,看到POST就知道是新增",她聽的很認真,理解的也很透徹。
"恩恩,返回的內容還是一樣"

{
    "orderId": "123456"
}

“接著是查詢會員卡余額,這次也簡化了很多”

GET /cards

{
    "cardId": "886333"
}

“這個請求我們還可以進一步優化為這樣”

GET /cards/886333

“Soga,直接把要查詢的卡號寫在后面了”
“沒錯,接著,取消訂單”

DELETE /orders/123456

Level 3 - 完美服務

“忽然有一天,有個顧客抱怨說,他買了咖啡后,不知道要怎么取消訂單,咖啡廳一個店員回了一句,你不會看我們的宣傳單嗎,上面不寫著:

DELETE /orders/{orderId}

顧客反問道,誰會去看那個啊,店員不服,又說到,你瞎了啊你......據說后面兩人吵著吵著還打了起來...”
“噗,真是悲劇...”

“有了這次教訓,店長決定,顧客下了單之后,不僅給他們返回訂單的編號,還給顧客返回所有可以對這個訂單做的操作,比如告訴用戶如何刪除訂單。現在,我們還是發出請求,請求內容和上一次一樣”

POST /orders

{
    "orderName": "latte"
}

“但是這次返回時多了些內容”

{
    "orderId": "123456",
    "link": {
        "rel": "cancel",
        "url": "/order/123456"
    }
}

“這次返回時多了一項link信息,里面包含了一個rel屬性和url屬性,rel是relationship的意思,這里的關系是cancel,url則告訴你如何執行這個cancel操作,接著你就可以這樣子來取消訂單啦”

DELETE /orders/123456

“哈哈,這服務真是貼心,以后再也不用擔心店員和顧客打起來了”

“訂單123456的客戶可以取餐了”,伴隨著咖啡廳的廣播,我們吃起了下午茶,一杯拿鐵,兩支吸管......

對程序員的話

用了大白話,給老婆講明白了RESTful的來龍去脈,當然,我還是有些話想說的,只是怕老婆聽完一臉懵逼,沒給她說:

1、
上面講的Level0~Level3,來自Leonard Richardson提出的Richardson Maturity Model

richardson-model.png

Level0和Level1最大的區別,就是Level1擁有了Restful的第一個特征——面向資源,這對構建可伸縮、分布式的架構是至關重要的。同時,如果把Level0的數據格式換成Xml,那么其實就是SOAP,SOAP的特點是關注行為和處理,和面向資源的RESTful有很大的不同。
Level0和Level1,其實都很挫,他們都只是把HTTP當做一個傳輸的通道,沒有把HTTP當做一種傳輸協議

Level2,真正將HTTP作為了一種傳輸協議,最直觀的一點就是Level2使用了HTTP動詞,GET/PUT/POST/DELETE/PATCH....,這些都是HTTP的規范,規范的作用自然是重大的,用戶看到一個POST請求,就知道它不是冪等的,使用時要小心,看到PUT,就知道他是冪等的,調用多幾次都不會造成問題,當然,這些的前提都是API的設計者和開發者也遵循這一套規范,確保自己提供的PUT接口是冪等的。

Level3,關于這一層,有一個古怪的名詞,叫HATEOAS(Hypertext As The Engine Of Application State),中文翻譯為“將超媒體格式作為應用狀態的引擎”,核心思想就是每個資源都有它的狀態,不同狀態下,可對它進行的操作不一樣。理解了這一層,再來看看REST的全稱,Representational State Transfer,中文翻譯為“表述性狀態轉移”,是不是好理解多了?

Level3的Restful API,給使用者帶來了很大的便利,使用者只需要知道如何獲取資源的入口之后的每個URI都可以通過請求獲得,無法獲得就說明無法執行那個請求

現在絕大多數的RESTful接口都做到了Level2的層次,做到Level3的比較少。當然,這個模型并不是一種規范,只是用來理解Restful的工具。所以,做到了Level2,也就是面向資源和使用Http動詞,就已經很Restful了。Restful本身也不是一種規范,我比較傾向于用"風格"來形容它。如果你想深入了解Level3,可以閱讀《Rest in Practice》第五章。

2、
我跟老婆講的時候,用的數據格式是JSON,但是要強調一點,Restful對數據格式沒有限制,就算你用的是XML或者其他格式,只要符合上面提到的幾個特征,也算Restful。

3、
關于如何寫出好的Restful API,阮一峰老師已經寫過一篇非常棒的文章:RESTful API 設計指南,這篇文章將指導你寫出優雅的Restful。

4、
我老婆長什么樣子?
看來是時候曬一下了:

我是誰?
沒錯,正是在下:

啥?什么梗?
歡迎關注《大雄和靜香的故事》:

這篇已經是第五集啦,上集中的tiny-facebook項目,已經加入了RESTful接口,代碼已更新到Github,tag是v2.0,checkout一下就可以拿到代碼啦,歡迎加星~~~

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,887評論 6 342
  • 一說到REST,我想大家的第一反應就是“啊,就是那種前后臺通信方式。”但是在要求詳細講述它所提出的各個約束,以及如...
    時待吾閱讀 3,443評論 0 19
  • spring官方文檔:http://docs.spring.io/spring/docs/current/spri...
    牛馬風情閱讀 1,699評論 0 3
  • 從今天開始,我開始學習Retrofit,整體Retrofit內容如下: 1、Retrofit解析1之前哨站——理解...
    隔壁老李頭閱讀 6,137評論 4 46
  • 不知道是不是最近太累的原因,總之自己沒覺得有什么,身體卻開始抗議了!大姨媽已經推遲了快二十天,每天失眠,身體疲倦,...
    花兒與月之歌閱讀 319評論 0 0