REST API應用很多,一方面提供公共API的平台越來越多,比如微博、微信等;一方面移動應用盛行,為Web端、Android端、IOS端、PC端,搭建一個統一的后台,以REST API的形式提供服務,也成為常見的開發模式。只是一個服務做得久了,就發現API的接口設計,如果能在一開始就好好設計一下,實在是功德無量的事。討論API接口設計的文章已有不少,本文重點談一談當請求處理出現異常的時候,出錯響應的內容和格式的設計。
比較自然的想法是,當有錯誤發生時,在響應中設置恰當的HTTP Status Code來指明這次請求是因為什么出錯的。因為HTTP協議的標准性,絕大多數客戶端可以理解收到的HTTP狀態碼,從而帶來一致的體驗。
但是,HTTP協議不可能定義出所有的出錯可能,滿足各種各樣的服務的需求。事實上,用來表示請求出錯的HTTP狀態碼只有24個,其中有18個4xx狀態碼用來表示客戶端錯誤,6個5xx妝台碼用來表示服務端錯誤。作為API的提供者,我們當然希望能夠盡可能的規范我們的出錯信息,提供更多的信息給調用者。因為API使用起來越是方便簡單,客戶就越有可能繼續使用我們提供的服務,同時,當出現問題需要排查的時候,我們的工作也更加容易。
下面這個出錯返回,列出了我認為錯誤信息里應當包含的內容。
{
"status": 404,
"code": 40483,
"message": "Oops! It looks like that file does not exist.",
"developerMessage": "File resource for path /uploads/foobar.txt does not exist. Please wait 10 minutes until the upload batch completes before checking again.",
"moreInfo": "http://www.mycompany.com/errors/40483",
"requestId": "x3kdsa32k23ds32e"
}
status
Status的內容與HTTP狀態碼內容相同,這個字段的存在,使得錯誤信息自包含,客戶端只需要解析HTTP響應的body部分,就可以獲取所有跟這次出錯相關的信息。
code
自定義錯誤碼。自定義錯誤碼的長度和個數都可以自己定義,這樣就突破了HTTP狀態碼的個數限制。例子中的錯誤碼是40483,其中404代表了請求的資源不存在,而83則制定了這次出錯,具體是哪一種資源不存在。
message
用戶可理解的錯誤信息,應當根據用戶的locale信息返回對應語言的版本。這個錯誤信息意在返回給使用客戶端的用戶閱讀,不應該包含任何技術信息。有了這個字段,客戶端的開發者在出錯時,能夠展示恰當的信息給最終用戶。
developerMessage
該出錯的詳細技術信息,提供給客戶端的開發者閱讀。可以包含Exception的信息、StackTrace,或者其它有用的技術信息。
moreInfo
給出一個URL,客戶端開發站訪問這個URL可以看到更詳細的關於該種出錯信息的描述。在該URL展示的網頁中,可以包含該出錯信息的定義,產生原因,解決辦法等等。
requestId
請求ID,服務為每一個請求唯一生成一個請求ID,當客戶端開發者無法自助解決問題時,可以聯絡服務開發者,同時提供該請求ID。一個好的服務,服務開發者應當可以根據此ID,定位到該次請求的所有相關log,進而定位問題,解決問題。
Reference
https://stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1/
