1. 程式人生 > >這次我讓你徹底弄懂 RESTful

這次我讓你徹底弄懂 RESTful

> 本文已收錄至 https://github.com/yessimida/yes ,這裡有我的所有文章分類彙總,歡迎 star! RESTful 想必大家都耳熟能詳。 但是為什麼要有 RESTful,RESTful 到底是什麼意思。 為什麼稱之為 RESTful 架構? 我不用 RESTful 不行嗎? 什麼樣才叫真正的 RESTful ? 其實網上 RESTful 的文章有挺多的,不過有些講的糊里糊塗的,而且很大部分都忽略了 HATEOAS。 在之前的面試中面試官就問過我,你怎麼理解 RESTful 的,英文全稱是啥?為什麼叫這個名字? **當時我人都傻了**。 面試官不講武德,針對我這個剛出社會的小夥子。 其實有很多人也稀裡糊塗的,也包括我自己。 就面向資源唄,不加動詞咯,還能咋滴,我加動詞不也能用嗎? 而且我之前還特不能理解,為啥這叫架構? 我特意搜尋了下架構的解釋。 > 軟體架構是有關軟體整體結構與元件的抽象描述,用於指導大型軟體系統各個方面的設計。 **整體結構與元件的抽象描述**。 RESTful 哪有什麼元件和結構之間的玩意? 所以就至今我寫下這篇文章的時候我也理解不了為什麼叫 RESTful **架構**。 可能是我對架構的理解太狹隘,還不到火候。 我個人只能理解成 RESTful 風格的 API 設計,也就是說 RESTful 只是一種指導風格,就像我們 Java 要用駝峰命名法。 那不用駝峰命名法程式碼就不能跑了嗎? 當然能跑,這只是一種希望大家都能遵循的規範。 對 RESTful 而言我覺得算不上規範,只能說指導風格。 來讓我們正式的進入對 RESTful 的剖析。 ## REST REST 不是一個單詞,是 **Re**presentational **S**tate **T**ransfer 的縮寫。 直譯過來就是**表述性狀態轉移**。 我對這個名字蒙了一年多,就不能說點能聽得懂的嘛。 從提出 REST 的論文中我翻了翻,沒有明說但是表達的意思是其實它還有個主語 Resource 。 所以是**資源的表述性狀態轉移**。 稍微可以理解一點了。 我們先不管什麼狀態轉移,大致先有點感覺。 知道 REST 之後 RESTful 就不難解釋了,加 ful 就是變形容詞了,比如 wonderful girl。 ![](https://img-blog.csdnimg.cn/img_convert/332b50e341ce61bd877752d6f158f240.png) 至此對名字稍微解釋了一下,疑惑還在沒事,咱們慢慢理。 ## REST 的核心 核心就是資源,**用 URL 定位資源,用 HTTP 動詞來描述所要做的操作**。 HTTP的提供了很多動詞:GET、PUT、POST、DELETE...... 這些動詞都是有含義的。 比如 GET 就是獲取資源,是查詢請求。 PUT 指的是修改資源,是冪等的。 POST 也是修改(新增也是一種修改),指的是不冪等的操作。 所以根據這些規範我們都能得知這次互動的一些動作,所以正確的使用姿勢如下: 比如獲取一個 user。 錯誤姿勢:`GET /getUserById?userId=1`。 正確姿勢:`GET /users/1`。 再比如新增 user。 錯誤姿勢:`POST /addUser` (省略body)。 正確姿勢:`POST /users` (省略body)。 可以看到 **HTTP 的動詞其實就能指代你要對資源做的操作**,所以不需要在 URL 上做一些東西,就把 URL 表明的東西就看做一個資源即可。 這裡注意要**用對 HTTP 動詞**,比如一個獲取資源的請求用 PUT,用了也能獲取資源但是這**不合適**。 其實更深一步的理解是 HTTP 是一個協議。 協議其實就是約定好的一個東西,協議就規定 GET 是獲取資源,那你非得在 URL 上再重複一遍或者所有請求不論增刪改都用 GET 這個動作,這其實就是沒有完全遵循這個協議。 可以說只是**把 HTTP 當成一個傳輸管道,而不是約定好的協議**。 這其實是對 HTTP 更深一層的認識,我認為也是 RESTful 被推出的原因。 當然理想很豐滿,現實很骨感,還是有很多人就 `getUserById`。 不過我個人覺得問題不大,公司統一就行。 ## HATEOAS 即 Hypermedia as the Engine of Application State 的縮寫,翻譯過來就是作為應用狀態引擎的超媒體。 這也是 REST 提出的設計。 是不是理解不了?其實很簡單。 例子我就不自己編了,抄一下 stackoverflow 回答上的例子。 比如你請求獲取使用者列表: ``` GET /users Accept: application/json+userdb ``` 此時的返回應該是: ``` 200 OK Content-Type: application/json+userdb { "users": [ { "id": 1, "name": "Emil", "country: "Sweden", "links": [ { "href": "/user/1", "rel": "self", "method": "GET" }, { "href": "/user/1", "rel": "edit", "method": "PUT" }, { "href": "/user/1", "rel": "delete", "method": "DELETE" } ] }, { "id": 2, ....省略..... } ], "links": [ { "href": "/user", "rel": "create", "method": "POST" } ] } ``` 重點就是這個 links,結果會返回你能對這個資源所做的操作。 比如對於 userId 是 1 的,你呼叫` PUT /user/1`就是做修改這個使用者,`DELETE /user/1 `就是刪除這個使用者。 最外層的 links 告訴你用 `POST /user` 就能再建立一個使用者。 這裡還有個隱藏資訊,可能看到外層的 links 沒有返回 DELETE 的資訊,**說明此時客戶端無法刪除使用者**! 所以說 **RESTful API 還需要在返回此時能做資源所做的操作**,這樣客戶端就知道它能做什麼。 它也不需要管具體怎麼做,反正返回裡面會告訴它 DELETE 就這樣這樣,POST 就這樣這樣。 沒告訴它的就是不能做的。 然後這個時候再去理解下**資源的表述性狀態轉移**,是不是感覺來了? 如果說上一 part 提到用 HTTP 的動詞來指代動作, URL 僅表示資源的現實是骨感的。 那麼 HATEOAS 的現實就是灰。 基本上沒幾家公司會這麼做。 就我**個人而言**這玩意沒啥用。 它的出發點是讓客戶端從響應就能得知對資源操作的入口,並且通過響應就得知哪些動作能執行。 聽起來好像有點用,但是就我目前的功力,我只能看到響應變得十分冗餘。 ![](https://img-blog.csdnimg.cn/img_convert/6ae06d6f4dd125673923d38011be53ae.png) ## 最後 這篇文章關於 RESTful API 具體的寫法我就提到一些,還有挺多的就自己查資料吧。 文章的目的是為了讓你理解 RESTful API,我再總結一下重點。 **HTTP 是協議,不是傳輸通道**。(對協議不理解的看我之前的 HTTP 分析) 所以協議約定了很多東西,推薦我們按照協議的用法進行客戶端和服務端的互動。 也就是 RESTful 表明的面向資源,通過 HTTP 動作 + URL 上的資源。 RESTful 還提到了 HATEOAS,雖說基本上沒什麼公司會這樣使用,但是它能讓你更好的理解 REST 這個名字的含義。 RESTful 是一種風格,你是否採用這種風格對你的程式執行沒有影響,類比駝峰命名來思考。 簡而言之,就是**不要在 URL 上表現出動作,用 HTTP 動詞代表動作,URL 上只做資源,僅此而已**。 **至於要不要嚴格遵循 RESTful 風格,我個人的看法是公司內部保持一致就行**。 歡迎加我好友進行深入地交流,備註「進群」,拉你進交流&內推群。 平日的面試題遇到難處,或者看某個知識點翻遍全網的資料還是感覺很模糊、不透徹,可以私聊我,給我留言。 遇到合適的我會整理寫出一篇文章,注意這個前提我認為合適的。 那種工作遇到很細節的場景的還是別了,這種問你上司比較合適:)。 ## 巨人的肩膀 *https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2* *http://www.ruanyifeng.com/blog/2011/09/restful.html* *https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming/3950863#3950863* *https://en.wikipedia.org/wiki/HATEOAS* 更多硬核文章等你來讀。 ![](https://oscimg.oschina.net/oscnet/up-898ebdaa9b29703e08f42924861811472c8.JPEG) --- > 微信搜尋【yes的練級攻略】,關注 yes,回覆【123】一份20W字的演算法刷題筆記等你來領,從一點點到億點點,我們下篇見。