後端面試:如何設計 HTTP 415 Unsupported Media Type 契約?
題干與適用場景
一個 API 的 POST 接受 JSON 與 CBOR,PATCH 接受 JSON Patch。客戶端送出錯誤的 Content-Type、內容編碼或 PATCH 文件格式時收到 415。請設計伺服器判定、回應標頭、錯誤本文字、客戶端恢復與版本演進。
這是後端 API 契約題。媒體類型和格式是題設,不代表線上頻率。
面試官考察點
- 能否區分請求的 Content-Type、Content-Encoding 與回應的 Accept。
- 能否說明 415 的邊界,不把所有解析錯誤歸入 415。
- 能否用 Accept-Patch 暴露 PATCH 能力並保持相容。
- 能否讓錯誤回應可行動且避免自動重試副作用。
回答前需要釐清的問題
- 415 是因媒體類型、內容編碼還是方法不支援該表示?
- 客戶端能否重新編碼正文,是否有穩定請求 ID?
- PATCH 支援哪些文件類型和資源版本條件?
- 閘道是否會改寫 Content-Type、編碼或錯誤本文字?
- 新媒體類型如何灰度,舊客戶端如何繼續工作?
30 秒回答框架
「415 表示目標方法拒絕處理目前請求表示的格式。伺服器先解析 Content-Type、參數和 Content-Encoding,再按方法與資源能力選擇解析器;Accept 描述客戶端希望收到的回應格式,不是請求格式。PATCH 資源可用 Accept-Patch 宣告支援的文件媒體類型。錯誤本文字返回穩定碼、實際收到和允許值及請求 ID,客戶端只在能重新編碼且操作可安全重播時重試。我會用相容矩陣和逐層指標驗證演進。」
分步深入解答
1. 劃分三個標頭語意
Content-Type 描述請求正文媒體類型,Content-Encoding 描述傳輸編碼,Accept 描述客戶端可接受的回應表示。伺服器不能用 Accept 判斷客戶端送出的 PATCH 文件,也不能把解壓失敗、損壞正文與不支援媒體類型混成一個原因。
2. 建立方法與資源能力表
每個方法和資源綁定允許的媒體類型與參數。例如 POST 可接受 application/json 與 application/cbor,PATCH 只接受註冊的 JSON Patch 文件。先檢查類型與編碼,再進入解析器;解析成功後仍要做 schema、權限和業務校驗。
PATCH /documents/42 HTTP/1.1
Content-Type: application/json-patch+json
Accept: application/json
Content-Length: 1283. 回傳準確的 415
媒體類型或內容編碼不支援時回傳 415,並給出穩定錯誤碼。若格式正確但欄位無效,使用領域校驗錯誤;若正文語法損壞,使用清晰的解析錯誤。回應中的 Accept 可說明伺服器願意返回的表示,不能假裝成請求媒體類型清單。
4. 暴露 PATCH 能力
RFC 5789 定義 Accept-Patch,資源可在 OPTIONS 或成功回應中宣告支援的 PATCH 文件媒體類型。客戶端據此選擇 JSON Patch 等格式;伺服器仍需在具體請求驗證資源版本、操作路徑和權限。能力宣告應與實際解析器保持一致。
5. 設計客戶端恢復
客戶端收到 415 後讀取穩定錯誤碼和允許類型,重新編碼正文或切換相容端點。只有正文可重建、請求沒有不可逆副作用、冪等鍵保持不變時才自動重試。不要因 415 重複提交可能已成功的 PATCH,也不要把 415 當成服務暫時不可用。
6. 控制演進與觀測
新增媒體類型先在閘道、伺服器和 SDK 灰度,保留舊類型相容窗口。指標按資源、方法、收到的類型、編碼、客戶端版本和拒絕原因統計;記錄請求 ID 與解析器版本,禁止記錄敏感正文。發現閘道改寫標頭時,分別比較入口和應用日誌。
高品質示範回答
「我把請求格式與回應格式分開。伺服器按方法和資源檢查 Content-Type 與 Content-Encoding,解析成功後再做 schema 和業務校驗;Accept 只用於協商回應。PATCH 資源透過 Accept-Patch 宣告可接受文件類型,實際請求仍要驗證版本與權限。415 錯誤本文字給穩定碼、收到值、允許值與請求 ID;客戶端只有可重編碼且安全重播時才重試。新類型透過相容矩陣和指標灰度,避免閘道或舊 SDK 改寫語意。」
常見錯誤
- 用 Accept 判斷請求正文 → 混淆請求和回應協商 → 檢查 Content-Type 與 Content-Encoding。
- 所有解析失敗都回傳 415 → 客戶端無法判斷修復路徑 → 區分媒體類型、語法和領域校驗。
- 宣告 Accept-Patch 卻沒有對應解析器 → 能力契約失真 → 讓宣告與實際實作同源驗證。
- 收到 415 自動原樣重試 → 永遠失敗或重複副作用 → 先改編碼並確認可重播。
- 只在應用記錄類型 → 閘道改寫後無法定位 → 比較逐層標頭和請求 ID。
追問及應對
Content-Type 正確但 Content-Encoding 不支援,仍然是 415 嗎?
RFC 9110 將不接受的請求內容編碼納入 415 適用範圍。錯誤本文字應指出編碼原因,客戶端先解壓或改用伺服器支援的編碼,再依冪等與正文可重建性決定是否重試。
為什麼不能只返回允許類型清單?
清單不說明目前方法、參數或版本約束。穩定錯誤碼、收到值、允許範圍、請求 ID 和文件連結更能驅動客戶端修復,同時避免暴露內部實作。
如何安全增加 CBOR 支援?
先在非關鍵資源啟用,驗證閘道透傳、解析器資源上限、schema 等價性和日誌脫敏;保留 JSON 回退,並按客戶端版本觀察 415、解析失敗和業務結果差異。