先看呼叫方要作甚麼決定
合作夥伴系統收到失敗回應後,可能要修正請求、重新取得授權、等候、交由人員處理,或因資源確實不存在而停止。單一句「發生錯誤」不足以支持任何決定。先列出業務流程中真正會遇到的情況,例如商品代碼不明、憑證過期、庫存資料暫時不可用或某欄位被拒絕。每種情況都應寫清楚安全的下一步,以及自動重試會否造成問題。這樣才能知道 API 需要表達哪些差別,再選回應格式。
HTTP 狀態碼本身要有正確含義。RFC 9110 定義一般客戶端及中介系統會使用的語義;RFC 9457 則在狀態碼不足以解釋應用問題時提供結構化資料。若 HTTP 回應是 200,但內容寫「錯誤」,監控及呼叫程式可能誤當成功。反過來,熟悉的情況若使用自訂狀態,也會迫使合作夥伴學習私有協定。先選語義相符的標準狀態,再於確有需要時加上穩定的問題類型,並在合作文件列出對照及例子。
一致地提供結構化詳情
RFC 9457 定義 application/problem+json 格式。type 指出問題種類;若使用可開啟的 HTTPS 類型網址,也可讓開發者找到說明。title 是該類型的簡短摘要,detail 解釋這一次發生了甚麼及可做甚麼;instance 可標識個別事件。可選的 status 欄位應與真正的 HTTP 狀態一致,因為一般軟件依照實際狀態碼運作。不要要求合作夥伴程式分析英文或中文句子才判斷錯誤種類;穩定的機器訊號應是 type。
只有呼叫方確實能使用的資料,才適合放進擴充欄位。驗證失敗回應可指出被拒絕的欄位及可接受輸入,但不應把密碼、私密資料或任意顧客內容原樣回傳到日誌。客服參考號可讓已清理的顧客報告連到伺服器紀錄,同時避免暴露系統結構。每個擴充欄位都要記錄其類型、是否可缺省,以及缺少時如何處理。RFC 9457 要求客戶端忽略不認識的擴充欄位,因此新增資訊不應暗中改變原有問題類型的意思。
按錯誤性質決定重試
重試提示既是技術指示,也是業務承諾。欄位驗證失敗要先修正資料,重送相同請求沒有用;授權失敗須檢查憑證或權限,亦不應高速重試。暫時性伺服器故障可能適合稍後再試,但呼叫方仍需避免把業務動作重複執行。RFC 9457 指出,合適的問題類型可以指定 Retry-After。只有伺服器能合理指出重試時間時才使用此標頭,不要把它當成每種錯誤的裝飾。
假設供應商送出建立訂單請求,連線在收到回應前中斷。即使有良好的錯誤格式,也不能單靠它判斷訂單是否已建立。合作夥伴應先以穩定的客戶端參考值查詢,或按雙方約定的冪等機制處理,才考慮重送。相反,若伺服器已清楚回報欄位錯誤,且尚未接受訂單,便可修正後提交有效請求。這些邊界應寫在問題類型旁,包括哪些請求可以安全重複;否則一句「重試」可能把不明狀態變成兩張真正訂單。
用商品匯入例子驗證
假設合作夥伴匯入一件商品,必須提供 SKU 及公開售價。若缺少 SKU,回應應使用合適的客戶端錯誤狀態及有文件說明的驗證類型;給人的 detail 可指出要修正的欄位,已定義的擴充欄位可讓程式在匯入報告中標示位置。若 SKU 存在,但合作夥伴無權操作該商品目錄,回應應指向權限處理,而非欄位修正。若庫存服務暫時不可用,則應回報伺服器端故障及適合該操作的恢復方法。同一流程的三種失敗,呼叫方需要三種不同動作。
匯入介面可顯示簡潔、可安全分享的訊息及受影響商品參考值;較完整的內部診斷留在工程紀錄。合作夥伴要能以 type 分組錯誤,而不用依賴已本地化的標題。若服務提供中文說明,使用繁體中文介面的人可讀到適合自己的解釋,但類型網址仍維持穩定。RFC 9457 容許人類可讀字串按語言協商;實作還應界定找不到所需語言時的後備方式。測試兩種語言是否導向相同決定,不必逐句對譯。
保護資料並測試契約
上線前,應假設每句錯誤訊息都可能顯示給合作夥伴職員、貼進支援工單及儲存在日誌。RFC 9457 明確提醒,問題回應不應洩漏實作細節、個人資料或堆疊紀錄。detail 或 instance 不應包含原始 SQL、存取權杖及顧客紀錄。公開訊息仍可有用,例如「缺少商品代碼」足以指示修正,無須顯示資料庫查詢。深入排查應靠關聯參考值及受控的伺服器日誌,讓處理事故的人與執行 API 復原的人各自看到所需資料。
契約測試不能只覆蓋成功路徑。要檢查 HTTP 狀態與可選的內容 status 相同、媒體類型正確、type 不會因翻譯而改變,以及每個有文件記載的欄位保持承諾的資料類型。測試無效輸入、憑證過期、沒有權限、資源不存在、暫時性故障,還有請求中斷且結果不明的情況。可請合作夥伴開發者只看回應及文件,說出下一個安全動作。若仍分不清應修正、等候、調查或停止,錯誤回應便未完成。
可建立一份精簡的合作夥伴錯誤目錄,避免不同開發團隊各自臨時寫訊息。每項應列出穩定的 type、常用 HTTP 狀態、業務情況、呼叫方可修正甚麼,以及應等候或聯絡支援的條件。難以理解的差別,可加入經清理的請求與回應例子。保證提供的欄位及僅供診斷的提示要分開記錄。這份目錄是開發者、客服及合作測試人員的共同契約,亦能在上線前發現問題類型被意外改動,避免既有整合做出錯誤的復原決定。
API 閘道、代理或應用框架可能在業務服務開始前已回報錯誤,這些回應未必帶有與應用錯誤相同的內容,但客戶端仍應能安全解讀 HTTP 狀態。應先界定哪一層負責身份驗證失敗、路徑不存在、請求過大及意外伺服器故障。測試必須看網絡上真正收到的回應,不可只做繞過中介層的單元測試。若閘道改寫狀態或內容,要記錄並修正互相矛盾的訊號。業務服務內設計得再漂亮的問題物件,也不能修補另一層產生的錯誤意思。
最後要考慮未能即時更新的合作夥伴程式。新增問題類型時,只要 HTTP 狀態仍正確,而且文件訂明遇到不認識的 type 應如何保守處理,例如顯示安全訊息並交由人員判斷,而不是猜測重試規則,舊客戶端便較易維持安全。刪除或重新定義既有 type 的影響較大,因為合作程式可能早已據此分支處理。這類改動應按 API 契約變更審核,並檢查兩種語言例子。目標是即使遇到從未見過的錯誤,呼叫方仍可做出審慎而正確的決定。
進行前先確認
- 為每種錯誤指定安全的呼叫方動作及合適的 HTTP 狀態。
- 保持問題類型穩定,並確保公開詳情可安全分享。
- 把結果不明的連線中斷與已明確回報的失敗分開測試。


