具代表性的面試主題

後端面試:如何用 HTTP Prefer 協商回應,又不破壞冪等與快取?

後端中等
Offer.cc 編輯團隊發佈 更新

題幹

一個批次 API 允許客戶端選擇回傳最小回應或完整表示,也可要求伺服器等待短時間完成。你會如何使用 Prefer、Preference-Applied 與快取策略,確保偏好未被滿足時客戶端仍能安全處理?

題幹與適用場景

批次寫入 API 的客戶端有不同頻寬與延遲目標:有的只需要狀態,有的需要完整資源表示,還有的願意等待幾秒以避免輪詢。請依 RFC 7240 設計 Prefer 請求標頭、Preference-Applied 回應標頭、錯誤處理、快取與降級。

Prefer 是請求偏好,不是伺服器必須滿足的指令。本題考察協定語意與 API 契約設計,不代表所有代理都會完整保留偏好標頭。

面試官考察點

  • 能否區分客戶端偏好與伺服器承諾,並在回應中明確實際採用的偏好。
  • 能否正確使用 return=minimalreturn=representationrespond-asyncwait
  • 能否處理 Prefer 導致的回應差異、Vary、快取鍵與代理相容性。
  • 能否讓重試、冪等鍵與非同步任務狀態在偏好未滿足時仍然安全。

回答前需要釐清的問題

  1. API 是安全讀取還是有副作用的寫入,是否已有冪等鍵?
  2. 完整表示的大小、生成成本與最大等待時間是多少?
  3. 客戶端能否接受 202 與狀態資源,是否支援輪詢或回呼?
  4. 中間代理是否會轉送 Prefer,快取是否可能共享?
  5. 偏好未滿足時,客戶端需要哪些穩定欄位?

30 秒回答框架

「Prefer 表達客戶端偏好,伺服器可以忽略或只部分採用;採用後用 Preference-Applied 明確回應。寫入請求可用 return=minimal 減少回應,除錯或同步場景可用 return=representation,長任務可用 respond-async 與有上限的 wait。我會把冪等鍵、202 狀態資源、快取 Vary 與客戶端降級一起設計:沒有 Preference-Applied 就按預設回應解析,不能假設偏好一定生效。」

分步驟深入解答

1. 把偏好當作可忽略協商

RFC 7240 定義 Prefer 請求標頭及 Preference-Applied 回應標頭。伺服器可選擇不套用偏好;因此回應體與狀態碼必須有穩定的預設契約,客戶端不能只因送出 Prefer 就跳過解析。

2. 選擇合適的偏好令牌

return=minimal 適合只需要成功確認的寫入;return=representation 適合希望取得更新後資源的同步呼叫。respond-async 表示客戶端接受非同步處理,wait=n 表示願意等待的時間上限。把這些令牌當預算提示,不要把 wait 當 SLA 保證。

3. 設計回應確認

採用偏好時回傳 Preference-Applied;未採用時可以省略該標頭,並按預設契約回應。非同步場景回傳 202、任務狀態 URI 與可追蹤 ID;同步超過等待預算後也應保持可查詢的任務狀態,而不是讓客戶端重複提交副作用。

http
POST /v1/imports HTTP/1.1
Prefer: return=minimal, respond-async, wait=3
Idempotency-Key: imp-8f2

HTTP/1.1 202 Accepted
Preference-Applied: respond-async
Location: https://api.example/imports/jobs/42
Cache-Control: no-store

4. 處理快取變體

如果同一安全 GET 的表示會隨 Prefer 改變,回應需要正確宣告 Vary,或避免把偏好相關回應放入共享快取。寫入回應通常使用 no-store;非同步狀態資源應定義短快取、ETag 或明確輪詢條件,避免中介層回傳過期進度。

5. 保證冪等與降級

Prefer 不改變操作語意,重試仍需遵守冪等性。寫入介面使用冪等鍵或業務去重鍵;客戶端看到 202、逾時或沒有 Preference-Applied 時,應查詢任務或按預設回應處理,不能因偏好未確認就再次建立資源。

6. 設定觀測與界限

記錄偏好令牌、是否採用、等待時長、回應大小、202 比例與代理鏈路。限制允許的 wait 範圍,拒絕過大值或將其截斷;對未知偏好採用忽略並記錄,避免把任意客戶端字串變成昂貴的執行路徑。

高品質示範回答

「我會把 Prefer 當作可忽略的客戶端偏好,而不是承諾。寫入介面預設回傳穩定狀態;客戶端需要輕量回應時送出 return=minimal,需要資源表示時送出 return=representation,長任務使用 respond-async 與受限的 wait。伺服器實際採用才回傳 Preference-Applied;非同步處理回傳 202、Location 與任務 ID。寫入使用冪等鍵,回應按安全性設定 no-store,表示差異透過 Vary 或快取隔離處理。客戶端沒有 Preference-Applied 時走預設解析並查詢任務,絕不因偏好不確定而重複副作用。」

常見錯誤

  • 把 Prefer 當強制指令 → 伺服器或代理可忽略它 → 用預設契約和 Preference-Applied 確認。
  • 把 wait 當完成保證 → 長任務仍可能逾時 → 限制預算並提供 202 狀態資源。
  • 非同步逾時後再次提交 → 產生重複副作用 → 使用冪等鍵並先查詢任務。
  • 忽略回應變體快取 → 客戶端拿到不匹配的表示 → 設定 Vary 或隔離快取。
  • 接受任意未知偏好並執行昂貴邏輯 → 攻擊者可放大資源消耗 → 未知偏好忽略、記錄並限制令牌。

追問及應對

沒有 Preference-Applied 是否代表請求失敗?

不代表。伺服器可能選擇預設行為或忽略偏好;客戶端應依穩定預設契約解析回應,只有協定或業務狀態明確失敗時才判定失敗。

return=minimal 能否用於所有寫入操作?

不能。它只表達客戶端不需要完整表示;若客戶端必須取得伺服器產生的版本號、校驗摘要或後續連結,就應請求表示或查詢資源,不能從空回應推斷欄位。

wait=5 是否會讓伺服器阻塞五秒?

不會構成硬性保證。它表示客戶端願意等待的偏好上限,伺服器可更早回應、忽略或轉為非同步;伺服器仍需執行自身逾時、並發與資源預算。

公開來源

同類題目