RESTful
是目前比較流行的接口路徑設計規範,基於HTTP,通常使用JSON方式定義,經過不一樣HttpMethod來定義對應接口的資源動做,如:新增(POST)、刪除(DELETE)、更新(PUT、PATCH)、查詢(GET)等。json
在RESTful
設計規範內,每個接口被認爲是一個資源請求,下面咱們針對每一種資源類型來看下API路徑設計。api
路徑設計
的注意事項
以下所示:app
請求方式 | 示例路徑 |
---|---|
POST |
https://api.yuqiyu.com/v1/users |
新增資源使用POST
方式來定義接口,新增資源數據經過RequestBody
方式進行傳遞,以下所示:curl
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
"name": "恆宇少年",
"age": 25,
"address": "山東濟南"
}'複製代碼
新增資源後接口應該返回該資源的惟一標識,好比:主鍵值。url
{
"id" : 1,
"name" : "恆宇少年"
}複製代碼
經過返回的惟一標識來操做該資源的其餘數據接口。spa
請求方式 | 示例路徑 |
備註 |
---|---|---|
DELETE |
https://api.yuqiyu.com/v1/users |
批量刪除資源 |
DELETE |
https://api.yuqiyu.com/v1/users/{id} | 刪除單個資源 |
刪除資源使用DELETE
方式來定義接口。設計
curl -X DELETE https://api.yuqiyu.com/v1/users/1複製代碼
將資源的主鍵值
經過路徑的方式傳遞給接口。代理
curl -X DELETE -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
"userIds": [
1,
2,
3
]
}'複製代碼
刪除多個資源時經過RequestBody
方式進行傳遞刪除條件的數據列表,上面示例中經過資源的主鍵值集合做爲刪除條件,固然也能夠經過資源的其餘元素做爲刪除的條件,好比:name
code
請求方式 | 示例路徑 |
備註 |
---|---|---|
PUT |
https://api.yuqiyu.com/v1/users/{id} | 更新單個資源的所有元素 |
PATCH |
https://api.yuqiyu.com/v1/users/{id} | 更新單個資源的部分元素 |
在更新資源數據時使用PUT
方式比較多,也是比較常見的,以下所示:orm
curl -X PUT -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users/1 -d '{
"name": "恆宇少年",
"age": 25,
"address": "山東濟南"
}'複製代碼
請求方式 | 示例路徑 |
備註 |
---|---|---|
GET |
https://api.yuqiyu.com/v1/users/{id} |
查詢單個資源 |
GET |
https://api.yuqiyu.com/v1/users?name={name} | 非惟一標識查詢資源 |
curl https://api.yuqiyu.com/v1/users/1複製代碼
經過惟一標識查詢資源時,使用路徑方式傳遞標識值,體現出層級關係。
curl https://api.yuqiyu.com/v1/users?name=恆宇少年複製代碼
查詢資源數據時不只僅都是經過惟一標識值做爲查詢條件,也可能會使用資源對象內的某一個元素做爲查詢條件。
請求方式 | 示例路徑 |
---|---|
GET |
https://api.yuqiyu.com/v1/users?page=1&size=20 |
分頁查詢資源時,咱們通常須要傳遞兩個參數做爲分頁的條件,page
表明了當前分頁的頁碼,size
則表明了每頁查詢的資源數量。
curl https://api.yuqiyu.com/v1/users?page=1&size=20複製代碼
若是分頁時須要傳遞查詢條件,能夠繼續追加請求參數。
https://api.yuqiyu.com/v1/users?page=1&size=20&name=恆宇少年複製代碼
有時咱們須要有動做性的修改某一個資源的元素內容,好比:重置密碼。
請求方式 | 示例路徑 |
備註 |
---|---|---|
POST |
https://api.yuqiyu.com/v1/users/{id}/actions/forget-password | - |
用戶的惟一標識在請求路徑中進行傳遞,而修改後的密碼經過RequestBody
方式進行傳遞,以下所示:
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users/1/actions/forget-password -d '{
"newPassword": "123456"
}'複製代碼
版本號是用於區分Api
接口的新老標準,比較流行的分別是接口路徑
、頭信息
這兩種方式傳遞。
咱們在部署接口時約定不一樣版本的請求使用HTTP代理
轉發到對應版本的接口網關,經常使用的請求轉發代理好比使用:Nginx
等。
這種方式存在一個弊端,若是多個版本同時將請求轉發到同一個網關
時,會致使具體版本的請求轉發失敗,咱們訪問v1
時可能會轉發到v2
,這並非咱們指望的結果,固然能夠在網關
添加一層攔截器,經過提取路徑上班的版本號來進行控制轉發。
# v1版本的請求
curl https://api.yuqiyu.com/v1/users/1
# v2版本的請求
curl https://api.yuqiyu.com/v2/users/1複製代碼
咱們能夠將訪問的接口版本經過HttpHeader
的方式進行傳遞,在網關
根據提取到的頭信息進行控制轉發到對應版本的服務,這種方式資源路徑的展示形式不會由於版本的不一樣而變化。
# v1版本的請求
curl -H 'Accept-Version:v1' https://api.yuqiyu.com/users/1
# v2版本的請求
curl -H 'Access-Version: v2' https://api.yuqiyu.com/users/1複製代碼
這兩個版本的請求可能請求參數、返回值都不同,可是請求的路徑是同樣的。
版本頭信息的Key
能夠根據自身狀況進行定義,推薦使用Accpet
形式,詳見Versioning REST Services。
在RESTful
設計規範內咱們須要充分的裏面HttpStatus
請求的狀態碼來判斷一個請求發送狀態,本次請求是否有效,常見的HttpStatus
狀態碼以下所示:
狀態碼 | 發生場景 |
---|---|
200 |
請求成功 |
201 |
新資源建立成功 |
204 |
沒有任何內容返回 |
400 |
傳遞的參數格式不正確 |
401 |
沒有權限訪問 |
403 |
資源受保護 |
404 |
訪問的路徑不正確 |
405 |
訪問方式不正確,GET請求使用POST方式訪問 |
410 |
地址已經被轉移,不可用 |
415 |
要求接口返回的格式不正確,好比:客戶端須要JSON格式,接口返回的是XML |
429 |
客戶端請求次數超過限額 |
500 |
訪問的接口出現系統異常 |
503 |
服務不可用,服務通常處於維護狀態。 |
針對不一樣的狀態碼咱們要作出不一樣的反饋,下面咱們先來看一個常見的參數異常
錯誤響應設計方式:
# 發起請求
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
"name": "",
"age": 25,
"address": "山東濟南"
}'
# 響應狀態
HttpStatus 200
# 響應內容
{
"code": "400",
"message": "用戶名必填."
}複製代碼
在服務端咱們能夠控制不一樣狀態碼、不一樣異常的固定返回格式,不該該將全部的異常請求都返回200
,而後對應返回錯誤,正確的方式:
# 發起請求
curl -X POST -H 'Content-Type: application/json' https://api.yuqiyu.com/v1/users -d '{
"name": "",
"age": 25,
"address": "山東濟南"
}'
# 響應狀態
HttpStatus 400
# 響應內容
{
"error": "Bad Request",
"message": "用戶名必填."
}複製代碼
接口的響應格式應該統一
。
每個請求成功的接口返回值外層格式應該統一,在服務端能夠採用實體方式進行泛型返回。
以下所示:
/**
* Api統一響應實體
* {@link #data } 每一個不一樣的接口響應的數據內容
* {@link #code } 業務異常響應狀態碼
* {@link #errorMsg} 業務異常消息內容
* {@link #timestamp} 接口響應的時間戳
*
* @author 恆宇少年 - 於起宇
*/
@Data
public class ApiResponse<T> implements Serializable {
private T data;
private String code;
private String errorMsg;
private Long timestamp;
}複製代碼
因爲每個API
的響應數據類型不一致,因此在上面採用的泛型的泛型進行返回,data
能夠返回任意類型的數據。
業務邏輯異常碼,好比:USERNOTFOUND(用戶不存在)這是接口的約定
對應code
值得描述。
請求響應的時間戳
RESTful
是API
的設計規範,並非全部的接口都應該遵循這一套規範來設計,不過咱們在設計初期更應該規範性,這樣咱們在後期閱讀代碼時根據路徑以及請求方式就能夠了解接口的主要完成的工做。