後端API介面的錯誤資訊返回規範
前言
最近我司要制定開發規範。在討論介面返回的時候,後端的同事詢問我們前端,錯誤資訊的返回,前端有什麼意見?
所以做了一些調研給到後端的同事做參考。
錯誤資訊返回
在使用API
時無可避免地會因為各種情況而導致介面返回錯誤的資訊。比如指定的query
引數錯誤,又或者method
不支援等,這些情況都會返回相關的錯誤資訊。另外伺服器不穩定或者停止運行了,也必須將錯誤資訊返回。
顯然,當錯誤發生的時候,只是籠統地返回“發生了錯誤”是不行的。如果前端不瞭解發生了什麼錯誤,也就不知道該怎麼去除錯,怎麼去修復這個bug
。所以說,必須向前端返回儘可能多的資訊,以便前端找到出錯的地方解決問題。
通過HTTP狀態碼錶示出錯資訊
首先必須選擇合適的HTTP
狀態碼,之前我司的後端API
沒有遵循這個規則。例如API
無論如何訪問,都會返回200
狀態碼,只在返回訊息體中的描述是否發生錯誤。
HTTP/1.1 200 OK Content-Type: application/json { "error": { "code": 2002, "message": "Invalid parameter" } }
雖然這麼處理前端也能理解API
的錯誤資訊,但由於HTTP
協議已經完整地定義了各個狀態碼所表示的含義,所以返回恰當的狀態碼才能提高前端正確識別錯誤的可能性。
如果出錯了,仍然返回200
狀態碼,有可能導致前端的處理髮生混亂,這種情況要一定要禁止。特別是通用的API
HTTP
協議,也給前端編寫錯誤處理增加了難度。
- 狀態碼分類
狀態碼 | 含義 |
---|---|
1xx | 訊息 |
2xx | 成功 |
3xx | 重定向 |
4xx | 前端原因引起的錯誤 |
5xx | 伺服器原因引起的錯誤 |
下面主要來了解一下4xx
和5xx
的錯誤碼:
4xx
-前端發生了錯誤
4xx
的狀態碼主要是用於描述因前端請求的問題而引發的錯誤,也就是說伺服器端不存在出錯問題,但伺服器端無法理解前端的請求,或者能理解但無法處理的請求。這一類的錯誤,統一使用4xx
狀態碼 | 名稱 | 說明 |
---|---|---|
400 | Bad Request | 表示其他錯誤,就是4xx都無法描述的前端發生的錯誤 |
401 | Authentication | 表示認證型別的錯誤 |
403 | Authorization | 表示授權的錯誤(認證和授權的區別在於:認證表示“識別前來訪問的是誰”,而授權則是“賦予特定使用者執行特定操作的許可權”) |
404 | Not Found | 表示訪問的資料不存在 |
405 | Method Not Allowd | 表示可以訪問介面,但是使用的HTTP方法不允許 |
406 | Not Acceptable | 表示API不支援前端指定的資料格式 |
408 | Request Timeout | 表示前端傳送的請求到伺服器所需的時間太長 |
409 | Confilct | 表示資源發生了衝突,比如使用已被註冊郵箱地址註冊時,就引起衝突 |
410 | Gone | 表示訪問的資源不存在。不單表示資源不存在,還進一步告知該資源該資源曾經存在但目前已消失 |
413 | Request Entity Too Large | 表示請求的訊息體過長而引發的錯誤 |
414 | Request-URI Too Large | 表示請求的首部過長而引發的錯誤 |
415 | Unsupported Media Type | 表示伺服器端不支援客戶端請求首部Content-Type裡指定的資料格式 |
416 | Range Not Satisfiable | 表示無法提供Range請求中的指定的那段包體 |
417 | Expectation Failed | 表示對於Expect請求頭部期待的情況無法滿足時的響應碼 |
421 | Misdirected Request | 表示伺服器認為這個請求不該發給它,因為它沒能力處理 |
426 | Upgrade Required | 表示伺服器拒絕基於當前HTTP協議提供服務,通過Upgrade頭部告知客戶端必須升級協議才能繼續處理 |
428 | Precondition Required | 表示使用者請求中缺失了條件類頭部,例如If-Match |
429 | Too Many Requests | 表示客戶端傳送請求的速率過快 |
431 | Request Header Fields Too Large | 表示請求的HEADER頭部大小超出限制 |
451 | Unavailable For Legal Reasons | 表示由於法律原因不可訪問 |
5xx
-伺服器端發生錯誤
5xx
狀態碼錶示錯誤由伺服器端的問題引發的。
狀態碼 | 名稱 | 說明 |
---|---|---|
500 | Internal Server Error | 表示伺服器內部錯誤,且不屬於以下錯誤型別 |
501 | Not Implemented | 表示伺服器不支援實現請求所需要的功能 |
502 | Bad Gateway | 代理伺服器無法獲取到合法資源 |
503 | Service Unavailable | 伺服器資源尚未準備好處理當前請求 |
504 | Gateway Timeout | 表示代理伺服器無法及時的從上游獲得響應 |
505 | HTTP Verson Not Supported | 表示請求使用的HTTP協議版本不支援 |
507 | Insufficient Storage | 表示伺服器沒有足夠的空間處理請求 |
508 | Loop Detected | 表示訪問資源時檢測到迴圈 |
511 | Network Authentication Required | 表示代理伺服器發現客戶端需要進行身份驗證才能獲得網路訪問許可權 |
向前端返回詳細的錯誤資訊
當錯誤發生時,除了需要返回相應的狀態碼之外,還需要返回詳情的錯誤資訊。因為狀態碼只是通用的描述錯誤的類別,一般無法表示實際發生的具體錯誤資訊。
比如說400
狀態碼,只是知道前端請求發生了錯誤,至於如何去修改,僅憑這個是沒有辦法找到bug
的。
通常來說:返回錯誤資訊的方法有兩種:
- 將資訊放入
HTTP
響應頭 - 將資訊通過
HTTP
響應體返回
1、通過自定義頭部,將詳細的錯誤資訊放入響應頭中
X-ERROR-CODE: 2020 X-ERROR-MESSAGE: Bad authentication token X-ERROR-INFO: http://api.example.com/v1/authentication
2、將錯誤資訊放入響應體中
{ "error": { "code": 2020, "message": "Bad authentication token", "info": "http://api.example.com/v1/authentication" } }
從前端的角度來考慮,通過響應體返回會更加容易處理。
這裡的錯誤程式碼的命名方式,按照後端自己的要求編寫即可。
通常情況下,會要求介面的錯誤資訊越詳細越好,但這也不是一定的,也會有特殊情況。
一般而言,前端會將後端介面的錯誤資訊原封不動的顯示出來,因為前端很難去判斷是否有涉密資訊或者讓使用者難堪的資訊。比如說A使用者遮蔽了B使用者,當B使用者想看A使用者的詳情時,如果正確的返回:“A使用者已遮蔽B使用者,無法獲取”的話,會讓雙方都難堪。這時就需要返回模稜兩可的資訊。這個就需要後端開發們自己去領悟。
針對預設返回與API
維護
某些介面在發生錯誤時會將HTML
返回。特別是發生404、503等錯誤時,這種情況就比較常見。當發生這些錯誤時,用於構建API
的Web
伺服器或者app
框架會直接返回出錯資訊,預設情況下大都是HTML
。
但雖說是發生了錯誤,前端依然在訪問中,所以仍然期待伺服器返回約定好的格式,比如JSON
。尤其在通過Accept
請求頭部或副檔名等指定了接收格式時。當然可以讓前端去檢查Content_Type
頭部,進行相應的處理。但如果前端處理的不好或者沒有處理,可能會導致app
崩潰。
尤其是公共api
,不能期望所有的使用者都嚴格遵循規範來處理好,這種api
算不上了好的api
。
關於API
的維護,正常來說,要避免不得不停止API
的發生。但特殊的時候也會不得不停止API
進行維護工作,這種情況需要返回503
狀態碼來告知前端當前API
已經停止工作。另外,因為這種停止操作不是意外而是有計劃進行的,所以要有API
何時重啟的時間資訊,將其傳送給前端。
不僅要預備好用於定期維護的狀態碼和出錯資訊的返回,還要使用Retry-After
頭部來告訴前端維護結束的時間。從SEO
的角度來看,這個方式對普通的web
站點的維護也同樣適用,也是Google
推薦的方法。
Retry-After
的值可以是某個具體的日期或從當前時刻算起至可正常訪問為止所需的秒數。
503 Service Temporarily Unavailable
Retry-After: Mon, 9 Sep 2020 20:00:00 GMT
從前端實現的角度來看,在返回503錯誤時,是期待前端能識別出API
地方Retry-After
值指定的時間等待,然後在API
重啟的時候再次訪問。
雖然這些處理都取決於前端的具體實現,後端無法對此進行控制,但依然要儘可能地返回詳細的資訊,方便前端處理並提升使用者體驗。
總結
主要是三個痛點:
- 必須選擇合適的
HTTP
狀態碼 - 向前端返回詳細的錯誤資訊
- 針對預設返回與
API
維護
作者: zhangwinwin
連結:後端API介面的錯誤資訊返回規範
來源:github