*今天偶爾在簡書上讀到一個作者解釋restFul解釋的風趣,且好理解。分享給大家~*
Level0 面向前臺
比如你要去星巴克前臺點單一杯拿鐵,這個過程,我們可以用簡單的json字符串來實現:
{
"addorder":{
"orderName":"latte"
}
}
這個字符串代表我們需要點單一杯拿鐵。
接着前臺返回給我們:
{
"orderId":"123456"
}
這個返回結果,代表您的定單編號是:123456,等下叫號取參。
突然想起自己有會員卡,所以又向前臺發出一個問題:
"queryBalance": {
"cardId": "88886666"
}
}
查詢會員卡餘額,會員卡號是:88886666
查詢結果返回來:
{
"balance": "0"
}
沒成想自己是個屌絲,所有的卡中存款餘額都是0,包括口袋,這可咋整,付不起拿鐵了~
接着就向前臺發送請求
{
"deleteOrder": {
"orderId": "123456"
}
}
請刪除這個定單,定單號爲:123456
Level1 面向資源
星巴克越做越大,一開始前臺既點單收費又做餐的,現在老闆決定多招些員工,專人專用。
點單的人專門負責點單和收費。
做餐的人專門負責做咖啡。
所以我的請求變爲:
/orders
{
"addOrder": {
"orderName": "latte"
}
}
多了個/orders什麼意思呢?
意思是,我們發送的請求是對着點單的人員的,他可以幫我們處理所有有關訂單的操作,包括新增訂單、修改訂單、取消訂單等操作,也就是面向資源的請求。
返回依舊是:
{
"orderId":"123456"
}
下面,我們還是要查詢會員卡餘額,這次請求的資源變成了cards
/cards
{
"queryBalance": {
"cardId": "886333"
}
}
“接下來是取消訂單”
/orders
{
“deleteOrder”: {
“orderId”: “123456”
}
}
清楚了吧。這就是面向資源的請求。
Level2 - 打上標籤
“接下來,店主還想繼續優化他的咖啡廳的服務流程,他發現負責處理訂單的員工,每次都要去訂單內容裏面看是新增訂單還是刪除訂單,還是其他的什麼操作,十分不方便,於是規定,所有新增資源的請求,都在請求上面寫上大大的‘POST’,表示這是一筆新增資源的請求”
“其他種類的請求,比如查詢類的,用‘GET’表示,刪除類的,用‘DELETE’表示”
“還有修改類的,修改分爲兩種,第一種,如果這個修改,無論發送多少次,最後一次修改後的資源,總是和第一次修改後的一樣,比如將拿鐵改爲貓屎,那麼用‘PUT’表示;第二種,如果這個修改,每次修改都會讓這個資源和前一次的不一樣,比如是加一杯咖啡,那麼這種請求用‘PATCH’或者‘POST’表示”.
點單:
POST /orders
{
"orderName": "latte"
}
返回值相同
接着是查詢會員卡餘額
GET /cards
{
"cardId": "886333"
}
還可以改爲:
GET /cards/886333
繼續,取消訂單
DELETE /orders/123456
Level3 完美服務
“忽然有一天,有個顧客抱怨說,他買了咖啡後,不知道要怎麼取消訂單,咖啡廳一個店員回了一句,你不會看我們的宣傳單嗎,上面不寫着:
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
上面講的Level0~Level3,來自Leonard Richardson提出的Richardson Maturity Model:
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》第五章。
Big things have small beginnings.大物始於小。
參考作者:如何給老婆解釋什麼是restful ——柳樹之