具代表性的面試主題

後端面試:如何設計 HTTP 415 Unsupported Media Type 契約?

後端困難
Offer.cc 編輯團隊發佈 更新

題幹

一個 API 同時支援 JSON、CBOR 和 JSON Patch,客戶端偶爾收到 415。你如何判斷拒絕原因、返回可行動資訊,並在不破壞舊客戶端下演進媒體類型?

題幹與適用場景

一個 API 的 POST 接受 JSON 與 CBOR,PATCH 接受 JSON Patch。客戶端送出錯誤的 Content-Type、內容編碼或 PATCH 文件格式時收到 415。請設計伺服器判定、回應標頭、錯誤本文字、客戶端恢復與版本演進。

這是後端 API 契約題。媒體類型和格式是題設,不代表線上頻率。

面試官考察點

  • 能否區分請求的 Content-Type、Content-Encoding 與回應的 Accept。
  • 能否說明 415 的邊界,不把所有解析錯誤歸入 415。
  • 能否用 Accept-Patch 暴露 PATCH 能力並保持相容。
  • 能否讓錯誤回應可行動且避免自動重試副作用。

回答前需要釐清的問題

  1. 415 是因媒體類型、內容編碼還是方法不支援該表示?
  2. 客戶端能否重新編碼正文,是否有穩定請求 ID?
  3. PATCH 支援哪些文件類型和資源版本條件?
  4. 閘道是否會改寫 Content-Type、編碼或錯誤本文字?
  5. 新媒體類型如何灰度,舊客戶端如何繼續工作?

30 秒回答框架

「415 表示目標方法拒絕處理目前請求表示的格式。伺服器先解析 Content-Type、參數和 Content-Encoding,再按方法與資源能力選擇解析器;Accept 描述客戶端希望收到的回應格式,不是請求格式。PATCH 資源可用 Accept-Patch 宣告支援的文件媒體類型。錯誤本文字返回穩定碼、實際收到和允許值及請求 ID,客戶端只在能重新編碼且操作可安全重播時重試。我會用相容矩陣和逐層指標驗證演進。」

分步深入解答

1. 劃分三個標頭語意

Content-Type 描述請求正文媒體類型,Content-Encoding 描述傳輸編碼,Accept 描述客戶端可接受的回應表示。伺服器不能用 Accept 判斷客戶端送出的 PATCH 文件,也不能把解壓失敗、損壞正文與不支援媒體類型混成一個原因。

2. 建立方法與資源能力表

每個方法和資源綁定允許的媒體類型與參數。例如 POST 可接受 application/jsonapplication/cbor,PATCH 只接受註冊的 JSON Patch 文件。先檢查類型與編碼,再進入解析器;解析成功後仍要做 schema、權限和業務校驗。

http
PATCH /documents/42 HTTP/1.1
Content-Type: application/json-patch+json
Accept: application/json
Content-Length: 128

3. 回傳準確的 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、解析失敗和業務結果差異。

公開來源

同類題目