1. 程式人生 > >[REST]RESTful規範

[REST]RESTful規範

什麼是RESTful

一種軟體架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器互動類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。

一、URI規範

1.不用大寫;

2.用中槓 - 不用下槓 _ ;

3.引數列表要encode;

4.URI中的名詞表示資源集合,使用複數形式。

5.在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞(特殊情況可以使用動詞),而且所用的名詞往往與資料庫的表格名對應。

資源集合 vs單個資源

URI表示資源的兩種方式:資源集合、單個資源。

資源集合:

       /zoos //所有動物園

       /zoos/1/animals //id為1的動物園中的所有動物

單個資源:

       /zoos/1//id為1的動物園

       /zoos/1;2;3//id為1,2,3的動物園

避免層級過深的URI

在url中表達層級,用於 按實體關聯關係進行物件導航 ,一般根據id導航。

過深的導航容易導致url膨脹,不易維護,如 GET /zoos/1/areas/3/animals/4 ,儘量使用查詢引數代替路徑中的實體導航,如 GET/animals?zoo=1&area=3 ;

二、   版本

應該將API的版本號放入到URI中

https://api.example.com/v1/zoos

三、 Request

HTTP方法

通過標準HTTP方法對資源CRUD:

GET:查詢(從伺服器取出資源一項或多項)

GET /zoos

GET /zoos/1

GET/zoos/1/employees

 

POST:建立單個新資源。 POST一般向“資源集合”型uri發起

POST/animals  //新增動物

POST/zoos/1/employees //為id為1的動物園僱傭員工

PUT:更新單個資源(全量),客戶端提供完整的更新後的資源。與之對應的是 PATCH,PATCH負責部分更新,客戶端提供要更新的那些欄位。 PUT/PATCH一般向“單個資源”型uri發起

PUT/animals/1

PUT /zoos/1

 

DELETE:刪除

DELETE/zoos/1/employees/2

DELETE/zoos/1/employees/2;4;5

DELETE/zoos/1/animals  //刪除id為1的動物園內的所有動物

 

HEAD / OPTION/ PATCH用的不多,就不多解釋了。

HEAD:獲取資源的元資料

OPTIONS:獲取資訊,關於資源的哪些屬性是客戶端可以改變的

PATCH:在伺服器更新資源(客戶端提供改變的屬性)

 

安全性和冪等性

1.     安全性 :不會改變資源狀態,可以理解為只讀的;

2.     冪等性 :執行1次和執行N次,對資源狀態改變的效果是等價的。

.

安全性

冪等性

GET

POST

×

×

PUT

×

DELETE

×

安全性和冪等性均不保證反覆請求能拿到相同的response。以 DELETE為例,第一次DELETE返回200表示刪除成功,第二次返回404提示資源不存在,這是允許的。

複雜查詢

查詢可以捎帶以下引數:

.

示例

備註

過濾條件

?type=1&age=16

允許一定的uri冗餘,如 /zoos/1 與 /zoos?id=1

排序

?sort=age&order=asc

指定返回結果按照哪個屬性排序,以及排序順序

投影

?whitelist=id,name,email

分頁

? page=2&per_page=100

指定第幾頁,以及每頁的記錄數

Bookmarker

經常使用的、複雜的查詢標籤化,降低維護成本。

如:GET /trades?status=closed&sort=created,desc

快捷方式:GET /trades#recently-closed或者GET /trades/recently-closed

 

狀態碼

    伺服器向用戶返回的狀態碼和提示資訊,常見的有以下一些(方括號中是該狀態碼對應的HTTP動詞)。

§200 OK - [GET]:伺服器成功返回使用者請求的資料,該操作是冪等的(Idempotent)。

§201 CREATED - [POST/PUT/PATCH]:使用者新建或修改資料成功。

§202 Accepted - [*]:表示一個請求已經進入後臺排隊(非同步任務)

§204 NO CONTENT - [DELETE]:使用者刪除資料成功。

§400 INVALID REQUEST - [POST/PUT/PATCH]:使用者發出的請求有錯誤,伺服器沒有進行新建或修改資料的操作,該操作是冪等的。

§401 Unauthorized - [*]:表示使用者沒有許可權(令牌、使用者名稱、密碼錯誤)。

§403 Forbidden - [*] 表示使用者得到授權(與401錯誤相對),但是訪問是被禁止的。

§404 NOT FOUND - [*]:使用者發出的請求針對的是不存在的記錄,伺服器沒有進行操作,該操作是冪等的。

§406 Not Acceptable - [GET]:使用者請求的格式不可得(比如使用者請求JSON格式,但是隻有XML格式)。

§410 Gone -[GET]:使用者請求的資源被永久刪除,且不會再得到的。

§422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個物件時,發生一個驗證錯誤。

§500 INTERNAL SERVER ERROR - [*]:伺服器發生錯誤,使用者將無法判斷髮出的請求是否成功。

狀態碼的完全列表參見這裡

 

URI失效

隨著系統發展,總有一些API失效或者遷移,對失效的API,返回404 not found 或 410 gone;對遷移的API,返回 301重定向。

 

四、Response

1.    不要包裝:

response的 body 直接就是資料,不要做多餘的包裝。錯誤示例:

{

   "success":true,

   "data":{"id":1,"name":"xiaotuan"},

}

2.    各HTTP方法成功處理後的資料格式:

·

response 格式

GET

單個物件、集合

POST

新增成功的物件

PUT/PATCH

更新成功的物件

DELETE

 

五、錯誤處理

1.     不要發生了錯誤但給2xx響應,客戶端可能會快取成功的http請求;

2.     正確設定http狀態碼,不要自定義;

3.     Response body提供

即:返回的資訊中將error作為鍵名,出錯資訊作為鍵值即可

1)錯誤的程式碼(日誌/問題追查);

2)錯誤的描述文字(展示給使用者)。

 

對第三點的實現稍微多說一點:

Java伺服器端一般用異常表示 RESTful API的錯誤。API 可能丟擲兩類異常:業務異常和非業務異常。 業務異常 由自己的業務程式碼丟擲,表示一個用例的前置條件不滿足、業務規則衝突等,比如引數校驗不通過、許可權校驗失敗。 非業務類異常 表示不在預期內的問題,通常由類庫、框架丟擲,或由於自己的程式碼邏輯錯誤導致,比如資料庫連線失敗、空指標異常、除0錯誤等等。

業務類異常必須提供2種資訊:

1.     如果丟擲該類異常,HTTP響應狀態碼應該設成什麼;

2.     異常的文字描述;

在Controller層使用統一的異常攔截器:

1.     設定 HTTP響應狀態碼:對業務類異常,用它指定的 HTTPcode;對非業務類異常,統一500;

2.     Response Body的錯誤碼:異常類名

3.     Response Body的錯誤描述:對業務類異常,用它指定的錯誤文字;對非業務類異常,線上可以統一文案如“伺服器端錯誤,請稍後再試”,開發或測試環境中用異常的 stacktrace,伺服器端提供該行為的開關。

常用的http狀態碼及使用場景:

狀態碼

使用場景

400 bad request

常用在引數校驗

401 unauthorized

未經驗證的使用者,常見於未登入。如果經過驗證後依然沒許可權,應該 403(即 authentication和 authorization的區別)。

403 forbidden

無許可權

404 not found

資源不存在

500 internal server error

非業務類異常

503 service unavaliable

由容器丟擲,自己的程式碼不要拋這個異常

 

六、其他

(1)API的身份認證應該使用OAuth2.0框架

(2)伺服器返回的資料格式,應該儘量使用JSON,避免使用XML

(3)比較複雜的介面不能確定是使用POST還是PUT時,要看具體的業務層程式碼,看看介面產生的結果是否冪等,如果冪等用PUT,相反用POST

      如:介面接收到一資源,資源存在更新,不存在插入新資料,這個介面就要用PUT

 

參考:https://blog.csdn.net/u013731455/art