發現不少RESTful API的錯誤代碼都是用HTTP的狀態碼(Status Code)做爲API的錯誤代碼,公司的一些產品也是如此,以下圖所示:
java
這種設計基本是把錯誤代碼依次映射到HTTP的狀態碼上,HTTP協議中定義的狀態碼基本包含下面幾類:數據庫
- 1xx Informational
- 2xx Success
- 3xx Redirection
- 4xx Client Error
- 5xx Server Error
好比對一個常見的新增用戶的API,返回的Code會設計以下:ui
- 201 建立成功
- 400 請求錯誤(驗證不經過,輸入錯誤)
- 401 操做未受權
- 409 用戶已存在
這種設計雖然能夠覆蓋大多數的狀況,但對於一些業務邏輯錯的話,就沒有對應的HTTP狀態碼匹配了。好比,新增用戶的時候,發現用戶組人數已經達到上限了,給一個什麼樣的狀態碼呢?或者發現數據庫沒法訪問了,又給一個什麼狀態碼呢?設計
HTTP狀態碼是HTTP協議的一部分,應用層的API是不該該知道下層協議的細節的。假若有其餘的業務錯誤沒法對應上現有的HTTP狀態碼,豈不是還的本身擴展出更多的狀態碼?這樣也會致使HTTP狀態碼和業務耦合,不管是服務端仍是客戶端。code
個人設計方案是,全部RESTful Web Service返回結果的結構都相同,不考慮改變HTTP返回的狀態嗎,而只是在返回結果中代表狀態和錯誤信息,大體結構以下:orm
{success:true|false, data:[]|{} [, error_code:, error_message:] } 經過success字段來代表這個請求的成功或失敗;若是成功,則能夠讀取data數據進行後續處理;若是失敗,能夠讀取error_code和error_message進行錯誤的處理。這樣的好處就是,既不用關心HTTP狀態碼,也不用對成功或失敗來處理不一樣的JSON結構。圖片
自定義錯誤代碼,HTTP狀態碼統一爲200。 { "error": { "message": "(#803) Some of the aliases you requested do not exist: me1", "type": "OAuthException", "code": 803 } }get
新浪 使用自定義錯誤代碼,錯誤的HTTP狀態碼是400。 http://open.weibo.com/wiki/Error_code產品
騰訊 使用自定義錯誤代碼,錯誤的HTTP狀態碼統一是200。 http://wiki.open.qq.com/wiki/%E5%85%AC%E5%85%B1%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8Eio
阿里巴巴
自定義錯誤代碼,不須要關心HTTP狀態碼 { "error_code":"450", "error_message":"Required argument memberId : expect [type: java.lang.String]", "exception":"Required argument memberId : expect [type: java.lang.String]" }