題目背景
一個批次 API 依序執行驗證、預留庫存與建立訂單。預留庫存失敗時,建立訂單沒有執行。面試官要求你設計錯誤回應,並解釋是否應該使用 HTTP 424。
核心考察點
- 能否區分 HTTP 狀態碼的標準語義與團隊自訂約定。
- 能否表達依賴圖中的部分完成、未執行與未知結果。
- 能否把冪等鍵、重試條件與錯誤詳情設計成同一份契約。
參考答案
424 的標準邊界
424(Failed Dependency)由 WebDAV RFC 4918 定義,表示目前方法因另一個操作失敗而無法完成。它不是「任何下游服務報錯」的通用別名。若介面不是 WebDAV,團隊可以採用 424,但必須在公開契約中說明語義、客戶端處理方式與相容性。
狀態碼選擇
412 Precondition Failed:請求帶有If-Match等前置條件,但條件不成立。409 Conflict:請求與目前資源狀態衝突,例如庫存版本已改變。424 Failed Dependency:目前步驟明確依賴同一請求或工作流中的失敗步驟,且本步驟未執行。5xx:服務端無法完成請求,原因屬於服務故障,而不是可由請求關係解釋的依賴結果。
不要只因依賴服務回傳 500 就機械映射成 424。先判斷本請求中的業務步驟是否因此被阻斷,以及客戶端是否能據此採取不同動作。
回應體與狀態機
建議使用 RFC 9457 Problem Details,回傳穩定的 type、title、status、detail 與擴充欄位,例如 blockedBy、operationId、retryable、completedSteps。擴充欄位屬於業務契約,必須版本化。
{
"type": "https://api.example.com/problems/failed-dependency",
"title": "Order creation was blocked",
"status": 424,
"detail": "Inventory reservation failed",
"blockedBy": "reserve-inventory",
"operationId": "op_123",
"retryable": true,
"completedSteps": ["validate-order"]
}重試與未知結果
只有 retryable=true 且使用同一冪等鍵時才自動重試。若連線在預留庫存提交後中斷,客戶端不能把逾時當成 424,因為服務端結果未知;應透過 operationId 查詢狀態。已完成的副作用不能靠再次送出請求假裝回滾,必要時要提供補償操作。
常見誤區
- 把 424 當作所有微服務錯誤的統一狀態碼。
- 只回傳一段可讀文字,沒有穩定錯誤類型與操作 ID。
- 收到 424 就盲目重試,導致重複扣庫存或重複建立訂單。
- 用 424 掩蓋服務端故障,使監控無法區分請求阻斷與平台故障。
追問方向
批次請求中可以部分成功嗎?
可以,但必須逐項回傳狀態、冪等鍵與依賴關係。整批回應的 HTTP 狀態只表達整體結果,不能取代每項結果;若業務要求原子性,就應明確全部回滾或全部不提交。
什麼時候回傳 409 而不是 424?
資源版本、庫存狀態等衝突屬於資源目前狀態問題,通常用 409。只有目前步驟因同一工作流中另一步失敗而未執行時,424 才能準確表達阻斷關係。
依賴服務 503 時目前請求回傳什麼?
若目前步驟因此無法執行且契約把它視為工作流依賴失敗,可回傳 424 並在詳情中保留根因;若這是服務整體不可用,應回傳 503,並配合 Retry-After 等服務級訊號。兩者要在監控與客戶端策略中區分。
如何測試這份契約?
涵蓋依賴成功、依賴拒絕、依賴逾時、提交後網路中斷、重複冪等鍵、部分完成與恢復查詢。斷言狀態碼、Problem Details 欄位、狀態機終態以及副作用次數,而不只斷言 HTTP 數字。
評分標準
合格
能準確說明 424 的 WebDAV 來源,給出 409、412、5xx 的邊界,並提出冪等鍵與未知結果查詢。
良好
能設計 Problem Details 擴充欄位、部分完成狀態與監控分類,說明自動重試的安全條件。
優秀
能從業務原子性、依賴圖、補償流程與版本化契約解釋每個選擇,並指出非 WebDAV 使用 424 時的相容性風險。
答題策略
先界定狀態碼的標準來源,再畫出步驟狀態與副作用邊界;最後用一份可查詢、可重試的錯誤契約把判斷落地。
參考資料
狀態碼規範
- RFC 4918:WebDAV(IETF)
HTTP 語義
- RFC 9110:HTTP Semantics(IETF)
錯誤格式
- RFC 9457:Problem Details for HTTP APIs(IETF)