RFC7807:API錯誤處理最佳實踐
在本文中,我想把我現在知道的關於rfc7807的知識分享給大家。rfc7807實際上定義了一個通用併合理的錯誤響應的API介面規範。
rfc7807詳細地址,各位開發者可點擊:https://tools.ietf.org/html/rfc7807
很多年來,我做過很多REST API的開發,並幫助許多企業,指導小夥伴們如何創建正確的API。
構建好的API的關鍵之一是錯誤處理與響應。
每家互聯網公司或研發部門都會自定義錯誤處理,「良好的錯誤編碼」結構應該包含以下三個基本標準,才能讓它能夠真正對用戶有用:
1、使用HTTP狀態碼
API的返回編碼採用HTTP狀態代碼方案中的標準代碼形式,通過使用這種非常通用的標準化來記錄狀態,不僅可以傳達錯誤的類型,而且還可以告知錯誤發生的位置(5xx意味著它是伺服器問題,而4xx意味著客戶端出錯了)。
2、內部參考ID,用於記錄特定錯誤的符號。
3、如果你有HTTP狀態碼方案或類似的參考資料,也可以取代HTTP狀態碼。
FHIR
如果我們以醫療FHIR標準為例,那麼錯誤就被定義為一個稱為操作結果的FHIR資源。
下面是一個錯誤響應的JSON實例:
{
"resourceType": "OperationOutcome",
"id": "exception",
"text": {
"status": "additional",
"div": "
SQL Link Communication Error (dbx = 34234)
"
},
"issue": [{
"severity": "error",
"code": "exception",
"details": {
"text": "SQL Link Communication Error (dbx = 34234)"
}
}]
}
這個產品的概念和界面都非常好,網址是https://www.hl7.org/fhir/operationoutcome.html,可以用於錯誤響應,當然也可以是響應成功的消息體。 如果想要使用它,需要了解A-Z的FHIR標準,可能對於某些人來說,FHIR概念可能有點設計過度。
Google的API使用以下錯誤響應消息體:
{
"error": {
"errors": [{
"domain": "global",
"reason": "invalidParameter",
"message": "Invalid string value: "asdf". Allowed values: [mostpopular]",
"locationType": "parameter",
"location": "chart"
}],
"code": 400,
"message": "Invalid string value: "asdf". Allowed values: [mostpopular]"
}
}
參考URL為:
https://developers.google.com/doubleclick-search/v2/standard-error-responses
其實我覺得Google的JSON結構有點奇怪:errors數組內包括著erros數組?
對於Facebook,錯誤響應消息體也不相同:
{
"error": {
"message": "Message describing the error",
"type": "OAuthException",
"code": 190,
"error_subcode": 460,
"error_user_title": "A title",
"error_user_msg": "A message",
"fbtrace_id": "EJplcsCHuLu"
}
}
Spotify
Spotify 返回的信息和Apache,Nginx的消息內容差不多:
{
"error": {
"status": 502,
"message": "Bad gateway."
}
}
淘寶
以下的是淘寶平台返回的消息,它是和XML相同的結構體:
11
Insufficient isv permissions
isv.permission-api-package-empty
還有其它更多的例子,大家看到每家的錯誤代碼和消息體都是千差萬別的。 如何參考錯誤鏈接,生成的錯誤代碼以及如何顯示編碼都會因不同的公司而異。
值得慶幸的是,標準化方法已經取得了進展:IETF組織最近發布了RFC 7807,其中描述了如何使用JSON對象作為在HTTP響應中對細節進行建模的方式。
RFC 7807支持
本文檔定義了一個「問題詳細信息」,作為在HTTP響應中移動設備可讀的錯誤細節的一種方式,以避免為HTTP API定義各種新的錯誤響應格式。
通過提供具有錯誤響應的更具體的機器可讀消息,API客戶端可以更有效地對錯誤作出反應,並最終從REST API測試角度和客戶端使API服務更加可靠。
一般來說,錯誤響應的目標是創建一個信息源,以便不僅向用戶通知問題,而且還能夠協助解決問題。簡單地說出一個問題並不能解決問題 - API出錯目前的狀態也是如此。
RFC 7807提供了用於從HTTP API返回問題詳細信息的標準格式。它規定了以下內容:
錯誤響應必須使用400或500範圍內的標準HTTP狀態碼來說明錯誤的類別。
錯誤響應將是Content-Type應用程序/問題,附加json或xml:application/problem + json,application/problem + xml的序列化格式。
錯誤響應將具有以下鍵(Key)值:
1.細節(字元串) - 特定錯誤的可讀描述。
2.類型(字元串) - 描述錯誤條件的文檔的URL(可選,如果沒有提供,則假定「about:blank」;應可被解析為可讀文檔)。
3.title(字元串) - 一般錯誤類型的簡短易讀的標題;對於給定的類型,標題不應改變。
4.狀態(號碼) - HTTP狀態碼;這是為了使所有信息都在一個地方,而且還要糾正由於使用代理伺服器而導致的狀態碼變化。
5.實例(字元串) - 此可選鍵可以選填,具有特定錯誤的唯一URI;這通常會指向該特定響應的錯誤日誌。
來看如下代碼:
{
"type": "https://example.net/validation-error",
"title": "Your request parameters didn"t validate.",
"invalid-params": [{
"name": "age",
"reason": "must be a positive integer"
}, {
"name": "color",
"reason": "must be "green", "red" or "blue""
}]
}
API開發者可以提供額外的密鑰,為消費者提供有關錯誤的更多信息,如果能夠定義新問題詳細信息,問題詳細信息也可以進行擴展。
新的消息類型定義:
1、類型URI(通常使用「http」或「https」)
2、一個描述合適的標題
3、與其一起使用的HTTP狀態代碼。
比如,如果要將HTTP API發布到購物車,則可能需要指出該用戶信用不足(上面的代碼示例),因此無法進行購買。
需要確定問題詳細信息的格式,如果API是基於JSON的,則為JSON格式;如果使用該格式,則為XML,以避免產生混亂。
還要確定適合用途的已定義的類型URI。如果有一個可用,可以重用URI。如果一個不可用,您可以創建並記錄一個新的類型URI(它應該在開發者的控制之下隨時間變得穩定),一個適當的標題和它將要使用的HTTP狀態代碼,以及它的含義以及告之別人如何處理。
請看如下代碼:
{
"type": "https://example.com/problems/request-parameters-missing",
"title": "required parameters are missing",
"detail": "The parameters: limit, date were not provided",
"limit_parameter_format": "number",
"date_parameter_format": "YYYY-mm-ddThh:mm-ss"
}
已經針對於某種語言的實現:
Java:https://github.com/zalando/problem-spring-web
Node.js:https://www.npmjs.com/package/problem-json
小結
下一步,使用RFC-7807-Problem Details的API規範將會越來越普遍,它具有非常好的靈活性和簡單性。人們可以自定義錯誤類型,只要包括有他們要鏈接的描述即可。API開發者可以根據自己的需要提供儘可能少或更多的細節,甚至可以根據環境(例如,生產與開發)來決定公開哪些信息。
使用RFC-7807可以讓API介面統一,使API更易於構建,測試與維護。越來越多的API開發者會應用這一標準。相信很快在客戶端和伺服器會統一標準,甚至AI處理常見的錯誤解決方案使用它也足夠使用。
作者:光頭彪
來源:21CTO
TAG:21世紀技術官學院 |