[ADP-403] 問題類型設計
TIP
2025.05.09 根據 RFC 9457,type 欄位必須足夠通用,但實務上有時需更細緻的子類型以利客戶端處理。經多方實作經驗,本規範明確建議:不應再設計 extraType
欄位,所有問題分類都應統一以 type
URI 表示,避免多餘欄位造成混淆。
核心原則
- URI 參考:必須(MUST)是人類可讀的 URI reference。
TIP
在 RFC9457 中,僅有提到 type 必須是相對或絕對 uri。 但是,根據 RFC9457 中提到 title 欄位是在人類無法理解 type 欄位時用來補充說明這個前提下,以及各個 HTTP Problem 的實作,本規範設計者認為 type 必須被設計為 human readable 的 uri reference。
也許當有一天應用程式成長到某個程度時,問題類型列表過長會進入到一個無法維護的狀態,此時有可能會變成設計 type: https://api.example.com/problems/1234088abc
作為問題類型是可以接受的,但是必須(MUST)真實存在此 uri 可以被解析到。
雖然 /1234088abc 也是正確的 uri,但是在語意理解的角度下,我們認為應該避免使用這種 uri 作為問題類型。
相對 URI:當不確定問題發布位置或是否發布時,可(MAY)使用相對 URI reference。
API 提供者應該(SHOULD)提供一個問題類型列表。
TIP
目前針對問題類型的設計可能會有疑慮:RFC9457 並未提供足夠的範例用以描述問題類型該如何設計,比如 究竟是:not-found
搭配 /books
作為 instance 還是 book-not-found
還是 book/not-found
? 以及 /problems
是否應該作為問題類型的前綴。
本規範建議先在單一應用程式內選擇統一一種做法後,等待之後規範推廣更加深遠的情況下去做應用間的問題類型統合。
以下暫時提供一些範例:
/problems/not-found
/problems/user-not-found
/problems/out-of-organization
/problems/invalid-license
因為 RFC9457 明確指出可以設計特定於某問題類型的欄位,因此倘若想要針對同一問題類型設計多種子類型,可以
- 考慮使用
/
或者-
來區分 - 使用特定於問題類型的擴充欄位
應該(SHOULD)盡可能地使用通用或已存在的問題類型。
如果確實需要其他資訊,可以針對問題類型(MAY)添加額外屬性(property)來擴展問題 JSON
http{ "type": "https://example.dev/problems/out-of-credit", "title": "您的請求無效。", "credit": 10, "remainingCredit": 0, }
設計流程
- 檢視現有的 HTTP 狀態碼,參考 ADP-200。
- 如果語意符合,使用該 HTTP 狀態碼的 URI reference 轉換(如:
/problems/not-found
)。
TIP
根據 RFC9457 原始的定義,about:blank
作為問題類型是被推薦的,但是本規範設計者認為如果要以 type 作為問題類型索引,應該盡可能直接指出而不是先看到 about:blank
再去檢查 status
代表的語意。
- 如果語意不符合,應查閱預定義的問題類型列表。
- 如果沒有匹配的狀態,應提出新類型,確保它們足夠通用。
- 使用
detail
欄位提供修正錯誤的方法。 - 使用
errors
欄位描述多個錯誤。
[已廢止] 子類型(extraType)設計提案
注意:本節為歷史設計,現已明確不建議使用 extraType 欄位,請統一以 type URI 表示所有問題分類。
早期考慮到有時需更細緻的子類型,曾提出 extraType
欄位設計。實務上,建議將子類型直接納入 type URI,例如:https://apidoc.alive.dev/problems/not-found/user-not-found
。
不再建議引入
extraType
欄位,請以 type URI 層級式設計分類。json{ "type": "https://example.com/problems/authentication-error/user-not-found", "title": "Authentication Error", "status": 409, "detail": "Your session has expired due to JWT", "errors": [] }
RFC 9457 合規指南
- 問題類型必須(MUST)是通用的,而非特定產品的。
- 應(SHOULD)最大化重用現有問題類型。
- 當 HTTP 狀態碼足夠時使用
about:blank
。查閱ADP-402 - 查閱ADP-406 以取得更多類型的範例。