避免自己寫的 url 被diss!建議看看這篇RestFul API簡明教程!
阿新 • • 發佈:2020-03-31
![](https://mmbiz.qpic.cn/mmbiz_png/iaIdQfEric9TwibWz8iardurUjC9jPyyKRb1Z8P2W7uFIa9JQPM8siaxWzU7iadNkc9MMyCgW0tibPIMKS8x0wkxuttJA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)
大家好我是 Guide 哥!這是我的第 **210** 篇優質原創!這篇文章主要分享了後端程式設計師必備的 RestFul API 相關的知識。
RestFul API 是每個程式設計師都應該瞭解並掌握的基本知識,我們在開發過程中設計 API 的時候也應該至少要滿足 RestFul API 的最基本的要求(比如介面中儘量使用名詞,使用 POST 請求建立資源,DELETE 請求刪除資源等等,示例:`GET /notes/id`:獲取某個指定 id 的筆記的資訊)。
如果你看 RestFul API 相關的文章的話一般都比較晦澀難懂,包括我下面的文章也會提到一些概念性的東西。但是,實際上我們平時開發用到的 RestFul API 的知識非常簡單也很容易概括!舉個例子,如果我給你下面兩個 url 你是不是立馬能知道它們是幹什麼的!這就是 RestFul API 的強大之處!
**RestFul API 可以你看到 url + http method 就知道這個 url 是幹什麼的,讓你看到了 http 狀態碼(status code)就知道請求結果如何。**
```
GET /classs:列出所有班級
POST /classs:新建一個班級
```
下面的內容只是介紹了我覺得關於 RestFul API 比較重要的一些東西,歡迎補充。
### 一、重要概念
REST,即 **REpresentational State Transfer** 的縮寫。這個片語的翻譯過來就是"表現層狀態轉化"。這樣理解起來甚是晦澀,實際上 REST 的全稱是 **Resource Representational State Transfe** ,直白地翻譯過來就是 **“資源”在網路傳輸中以某種“表現形式”進行“狀態轉移”** 。如果還是不能繼續理解,請繼續往下看,相信下面的講解一定能讓你理解到底啥是 REST 。
我們分別對上面涉及到的概念進行解讀,以便加深理解,不過實際上你不需要搞懂下面這些概念,也能看懂我下一部分要介紹到的內容。不過,為了更好地能跟別人扯扯 “RestFul API”我建議你還是要好好理解一下!
- **資源(Resource)** :我們可以把真實的物件資料稱為資源。一個資源既可以是一個集合,也可以是單個個體。比如我們的班級 classs 是代表一個集合形式的資源,而特定的 class 代表單個個體資源。每一種資源都有特定的 URI(統一資源定位符)與之對應,如果我們需要獲取這個資源,訪問這個 URI 就可以了,比如獲取特定的班級:`/class/12`。另外,資源也可以包含子資源,比如 `/classs/classId/teachers`:列出某個指定班級的所有老師的資訊
- **表現形式(Representational)**:"資源"是一種資訊實體,它可以有多種外在表現形式。我們把"資源"具體呈現出來的形式比如 json,xml,image,txt 等等叫做它的"表現層/表現形式"。
- **狀態轉移(State Transfer)** :大家第一眼看到這個詞語一定會很懵逼?內心 BB:這尼瑪是啥啊? 大白話來說 REST 中的狀態轉移更多地描述的伺服器端資源的狀態,比如你通過增刪改查(通過 HTTP 動詞實現)引起資源狀態的改變。ps:網際網路通訊協議 HTTP 協議,是一個無狀態協議,所有的資源狀態都儲存在伺服器端。
綜合上面的解釋,我們總結一下什麼是 RESTful 架構:
1. 每一個 URI 代表一種資源;
2. 客戶端和伺服器之間,傳遞這種資源的某種表現形式比如 json,xml,image,txt 等等;
3. 客戶端通過特定的 HTTP 動詞,對伺服器端資源進行操作,實現"表現層狀態轉化"。
### 二、REST 介面規範
#### 1、動作
- GET :請求從伺服器獲取特定資源。舉個例子:`GET /classs`(獲取所有班級)
- POST :在伺服器上建立一個新的資源。舉個例子:`POST /classs`(建立班級)
- PUT :更新伺服器上的資源(客戶端提供更新後的整個資源)。舉個例子:`PUT /classs/12`(更新編號為 12 的班級)
- DELETE :從伺服器刪除特定的資源。舉個例子:`DELETE /classs/12`(刪除編號為 12 的班級)
- PATCH :更新伺服器上的資源(客戶端提供更改的屬性,可以看做作是部分更新),使用的比較少,這裡就不舉例子了。
#### 2、路徑(介面命名)
路徑又稱"終點"(endpoint),表示 API 的具體網址。實際開發中常見的規範如下:
1. **網址中不能有動詞,只能有名詞,API 中的名詞也應該使用複數。** 因為 REST 中的資源往往和資料庫中的表對應,而資料庫中的表都是同種記錄的"集合"(collection)。**如果 API 呼叫並不涉及資源(如計算,翻譯等操作)的話,可以用動詞。** 比如:`GET /calculate?param1=11¶m2=33`
2. 不用大寫字母,建議不用中槓 - 不用下槓 \_ 比如邀請碼寫成 `invitation-code`而不是 ~~invitation_code~~
Talk is cheap!來舉個實際的例子來說明一下吧!現在有這樣一個 API 提供班級(class)的資訊,還包括班級中的學生和教師的資訊,則它的路徑應該設計成下面這樣。
**介面儘量使用名詞,禁止使用動詞。** 下面是一些例子:
```
GET /classs:列出所有班級
POST /classs:新建一個班級
GET /classs/classId:獲取某個指定班級的資訊
PUT /classs/classId:更新某個指定班級的資訊(一般傾向整體更新)
PATCH /classs/classId:更新某個指定班級的資訊(一般傾向部分更新)
DELETE /classs/classId:刪除某個班級
GET /classs/classId/teachers:列出某個指定班級的所有老師的資訊
GET /classs/classId/students:列出某個指定班級的所有學生的資訊
DELETE classs/classId/teachers/ID:刪除某個指定班級下的指定的老師的資訊
```
反例:
```
/getAllclasss
/createNewclass
/deleteAllActiveclasss
```
理清資源的層次結構,比如業務針對的範圍是學校,那麼學校會是一級資源:`/schools`,老師: `/schools/teachers`,學生: `/schools/students` 就是二級資源。
#### 3、過濾資訊(Filtering)
如果我們在查詢的時候需要新增特定條件的話,建議使用 url 引數的形式。比如我們要查詢 state 狀態為 active 並且 name 為 guidegege 的班級:
```
GET /classs?state=active&name=guidegege
```
比如我們要實現分頁查詢:
```
GET /classs?page=1&size=10 //指定第1頁,每頁10個數據
```
#### 4、狀態碼(Status Codes)
**狀態碼範圍:**
| 2xx:成功 | 3xx:重定向 | 4xx:客戶端錯誤 | 5xx:伺服器錯誤 | |
| --------- | -------------- | ---------------- | --------------- | ---- |
| 200 成功 | 301 永久重定向 | 400 錯誤請求 | 500 伺服器錯誤 | |
| 201 建立 | 304 資源未修改 | 401 未授權 | 502 閘道器錯誤 | |
| | | 403 禁止訪問 | 504 閘道器超時 | |
| | | 404 未找到 | | |
| | | 405 請求方法不對 | | |
| | | | | |
### 三 HATEOAS
> **RestFul 的極致是 hateoas ,但是這個基本不會在實際專案中用到。**
上面是 RESTful API 最基本的東西,也是我們平時開發過程中最容易實踐到的。實際上,RESTful API 最好做到 Hypermedia,即返回結果中提供連結,連向其他 API 方法,使得使用者不查文件,也知道下一步應該做什麼。
比如,當用戶向 api.example.com 的根目錄發出請求,會得到這樣一個文件。
```javascript
{"link": {
"rel": "collection https://www.example.com/classs",
"href": "https://api.example.com/classs",
"title": "List of classs",
"type": "application/vnd.yourformat+json"
}}
```
上面程式碼表示,文件中有一個 link 屬性,使用者讀取這個屬性就知道下一步該呼叫什麼 API 了。rel 表示這個 API 與當前網址的關係(collection 關係,並給出該 collection 的網址),href 表示 API 的路徑,title 表示 API 的標題,type 表示返回型別 Hypermedia API 的設計被稱為[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS)。
在 Spring 中有一個叫做 HATEOAS 的 API 庫,通過它我們可以更輕鬆的建立除符合 HATEOAS 設計的 API。