避免自己寫的 Url 被diss!建議看看這篇RestFul API簡(jiǎn)明教程!
RestFul API 是每個(gè)程序員都應(yīng)該了解并掌握的基本知識(shí),我們?cè)陂_(kāi)發(fā)過(guò)程中設(shè)計(jì) API 的時(shí)候也應(yīng)該至少要滿足 RestFul API 的最基本的要求(比如接口中盡量使用名詞,使用 POST 請(qǐng)求創(chuàng)建資源,DELETE 請(qǐng)求刪除資源等等,示例:GET /notes/id:獲取某個(gè)指定 id 的筆記的信息)。
如果你看 RestFul API 相關(guān)的文章的話一般都比較晦澀難懂,包括我下面的文章也會(huì)提到一些概念性的東西。但是,實(shí)際上我們平時(shí)開(kāi)發(fā)用到的 RestFul API 的知識(shí)非常簡(jiǎn)單也很容易概括!舉個(gè)例子,如果我給你下面兩個(gè) url 你是不是立馬能知道它們是干什么的!這就是 RestFul API 的強(qiáng)大之處!
RestFul API 可以你看到 url + http method 就知道這個(gè) url 是干什么的,讓你看到了 http 狀態(tài)碼(status code)就知道請(qǐng)求結(jié)果如何。
- GET /classs:列出所有班級(jí)
- POST /classs:新建一個(gè)班級(jí)
下面的內(nèi)容只是介紹了我覺(jué)得關(guān)于 RestFul API 比較重要的一些東西,歡迎補(bǔ)充。
一、重要概念
REST,即 REpresentational State Transfer 的縮寫。這個(gè)詞組的翻譯過(guò)來(lái)就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。這樣理解起來(lái)甚是晦澀,實(shí)際上 REST 的全稱是 Resource Representational State Transfe ,直白地翻譯過(guò)來(lái)就是 “資源”在網(wǎng)絡(luò)傳輸中以某種“表現(xiàn)形式”進(jìn)行“狀態(tài)轉(zhuǎn)移” 。如果還是不能繼續(xù)理解,請(qǐng)繼續(xù)往下看,相信下面的講解一定能讓你理解到底啥是 REST 。
我們分別對(duì)上面涉及到的概念進(jìn)行解讀,以便加深理解,不過(guò)實(shí)際上你不需要搞懂下面這些概念,也能看懂我下一部分要介紹到的內(nèi)容。不過(guò),為了更好地能跟別人扯扯 “RestFul API”我建議你還是要好好理解一下!
- 資源(Resource) :我們可以把真實(shí)的對(duì)象數(shù)據(jù)稱為資源。一個(gè)資源既可以是一個(gè)集合,也可以是單個(gè)個(gè)體。比如我們的班級(jí) classs 是代表一個(gè)集合形式的資源,而特定的 class 代表單個(gè)個(gè)體資源。每一種資源都有特定的 URI(統(tǒng)一資源定位符)與之對(duì)應(yīng),如果我們需要獲取這個(gè)資源,訪問(wèn)這個(gè) URI 就可以了,比如獲取特定的班級(jí):/class/12。另外,資源也可以包含子資源,比如 /classs/classId/teachers:列出某個(gè)指定班級(jí)的所有老師的信息
- 表現(xiàn)形式(Representational):"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來(lái)的形式比如 json,xml,image,txt 等等叫做它的"表現(xiàn)層/表現(xiàn)形式"。
- 狀態(tài)轉(zhuǎn)移(State Transfer) :大家第一眼看到這個(gè)詞語(yǔ)一定會(huì)很懵逼?內(nèi)心 BB:這尼瑪是啥啊?大白話來(lái)說(shuō) REST 中的狀態(tài)轉(zhuǎn)移更多地描述的服務(wù)器端資源的狀態(tài),比如你通過(guò)增刪改查(通過(guò) HTTP 動(dòng)詞實(shí)現(xiàn))引起資源狀態(tài)的改變。ps:互聯(lián)網(wǎng)通信協(xié)議 HTTP 協(xié)議,是一個(gè)無(wú)狀態(tài)協(xié)議,所有的資源狀態(tài)都保存在服務(wù)器端。
綜合上面的解釋,我們總結(jié)一下什么是 RESTful 架構(gòu):
- 每一個(gè) URI 代表一種資源;
- 客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)形式比如 json,xml,image,txt 等等;
- 客戶端通過(guò)特定的 HTTP 動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。
二、REST 接口規(guī)范
1、動(dòng)作
- GET :請(qǐng)求從服務(wù)器獲取特定資源。舉個(gè)例子:GET /classs(獲取所有班級(jí))
- POST :在服務(wù)器上創(chuàng)建一個(gè)新的資源。舉個(gè)例子:POST /classs(創(chuàng)建班級(jí))
- PUT :更新服務(wù)器上的資源(客戶端提供更新后的整個(gè)資源)。舉個(gè)例子:PUT /classs/12(更新編號(hào)為 12 的班級(jí))
- DELETE :從服務(wù)器刪除特定的資源。舉個(gè)例子:DELETE /classs/12(刪除編號(hào)為 12 的班級(jí))
- PATCH :更新服務(wù)器上的資源(客戶端提供更改的屬性,可以看做作是部分更新),使用的比較少,這里就不舉例子了。
2、路徑(接口命名)
路徑又稱"終點(diǎn)"(endpoint),表示 API 的具體網(wǎng)址。實(shí)際開(kāi)發(fā)中常見(jiàn)的規(guī)范如下:
- 網(wǎng)址中不能有動(dòng)詞,只能有名詞,API 中的名詞也應(yīng)該使用復(fù)數(shù)。 因?yàn)?REST 中的資源往往和數(shù)據(jù)庫(kù)中的表對(duì)應(yīng),而數(shù)據(jù)庫(kù)中的表都是同種記錄的"集合"(collection)。如果 API 調(diào)用并不涉及資源(如計(jì)算,翻譯等操作)的話,可以用動(dòng)詞。 比如:GET /calculate?param1=11¶m2=33
- 不用大寫字母,建議不用中杠 - 不用下杠 _ 比如邀請(qǐng)碼寫成 invitation-code而不是invitation_code
Talk is cheap!來(lái)舉個(gè)實(shí)際的例子來(lái)說(shuō)明一下吧!現(xiàn)在有這樣一個(gè) API 提供班級(jí)(class)的信息,還包括班級(jí)中的學(xué)生和教師的信息,則它的路徑應(yīng)該設(shè)計(jì)成下面這樣。
接口盡量使用名詞,禁止使用動(dòng)詞。 下面是一些例子:
- GET /classs:列出所有班級(jí)
- POST /classs:新建一個(gè)班級(jí)
- GET /classs/classId:獲取某個(gè)指定班級(jí)的信息
- PUT /classs/classId:更新某個(gè)指定班級(jí)的信息(一般傾向整體更新)
- PATCH /classs/classId:更新某個(gè)指定班級(jí)的信息(一般傾向部分更新)
- DELETE /classs/classId:刪除某個(gè)班級(jí)
- GET /classs/classId/teachers:列出某個(gè)指定班級(jí)的所有老師的信息
- GET /classs/classId/students:列出某個(gè)指定班級(jí)的所有學(xué)生的信息
- DELETE classs/classId/teachers/ID:刪除某個(gè)指定班級(jí)下的指定的老師的信息
反例:
- /getAllclasss
- /createNewclass
- /deleteAllActiveclasss
理清資源的層次結(jié)構(gòu),比如業(yè)務(wù)針對(duì)的范圍是學(xué)校,那么學(xué)校會(huì)是一級(jí)資源:/schools,老師: /schools/teachers,學(xué)生: /schools/students 就是二級(jí)資源。
3、過(guò)濾信息(Filtering)
如果我們?cè)诓樵兊臅r(shí)候需要添加特定條件的話,建議使用 url 參數(shù)的形式。比如我們要查詢 state 狀態(tài)為 active 并且 name 為 guidegege 的班級(jí):
- GET /classs?state=active&name=guidegege
比如我們要實(shí)現(xiàn)分頁(yè)查詢:
- GET /classs?page=1&size=10 //指定第1頁(yè),每頁(yè)10個(gè)數(shù)據(jù)
4、狀態(tài)碼(Status Codes)
三、HATEOAS
RestFul 的極致是 hateoas ,但是這個(gè)基本不會(huì)在實(shí)際項(xiàng)目中用到。
上面是 RESTful API 最基本的東西,也是我們平時(shí)開(kāi)發(fā)過(guò)程中最容易實(shí)踐到的。實(shí)際上,RESTful API 最好做到 Hypermedia,即返回結(jié)果中提供鏈接,連向其他 API 方法,使得用戶不查文檔,也知道下一步應(yīng)該做什么。
比如,當(dāng)用戶向 api.example.com 的根目錄發(fā)出請(qǐng)求,會(huì)得到這樣一個(gè)文檔。
- {"link": {
- "rel": "collection https://www.example.com/classs",
- "href": "https://api.example.com/classs",
- "title": "List of classs",
- "type": "application/vnd.yourformat+json"
- }}
上面代碼表示,文檔中有一個(gè) link 屬性,用戶讀取這個(gè)屬性就知道下一步該調(diào)用什么 API 了。rel 表示這個(gè) API 與當(dāng)前網(wǎng)址的關(guān)系(collection 關(guān)系,并給出該 collection 的網(wǎng)址),href 表示 API 的路徑,title 表示 API 的標(biāo)題,type 表示返回類型 Hypermedia API 的設(shè)計(jì)被稱為HATEOAS。
在 Spring 中有一個(gè)叫做 HATEOAS 的 API 庫(kù),通過(guò)它我們可以更輕松的創(chuàng)建除符合 HATEOAS 設(shè)計(jì)的 API。