這次我讓你徹底弄懂 RESTful
阿新 • • 發佈:2020-12-02
> 本文已收錄至 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字的演算法刷題筆記等你來領,從一點點到億點點,我們下篇見。