自從大多數人開始建構 Web 應用程式以來,我們的資料檢索選項一直感覺像是一種持續的架構妥協。
在設計搜尋端點、複雜篩選面板或深層巢狀查詢時,我們面臨一個令人沮喪的兩難選擇:
-
使用
GET: 它安全、冪等,且能被 CDN 與瀏覽器大量快取。但它強迫你將龐大的 JSON 物件或複雜搜尋條件序列化到 URL 查詢字串中,容易觸及瀏覽器長度限制、參數難以閱讀,以及敏感資料外洩到伺服器存取記錄的風險。 -
使用
POST: 它提供乾淨的請求主體,可安全傳送豐富的酬載。然而,POST在語意上預設為非安全且非冪等。快取層、負載平衡器與反向代理會拒絕快取它,且自動網路重試變得危險。
我們已經忍受這些折衷方案數十年。但 Web 架構環境正在改變。IETF 已正式標準化一個全新的核心方法:QUERY (RFC 10008)。
讓我們來解析它解決了什麼問題、如何運作,以及我們在現代 API 設計中應如何思考它。
QUERY 解決的核心問題
本質上,QUERY 引入了一個乾淨且語意清晰的解決方案:它充當「帶有主體的安全 GET」。
為了理解為什麼這是一項受歡迎的補充,讓我們看看官方規範下核心檢索方法的比較:
| 屬性 | GET |
QUERY |
POST |
|---|---|---|---|
| 安全(唯讀) | 是 | 是 | 可能否 |
| 冪等(可重試) | 是 | 是 | 可能否 |
| 具備請求主體 | 否 | 是 | 是 |
| 可快取 | 是 | 是 | 受限 |
透過將讀取資料的動作與傳輸大型酬載的機制分離,QUERY 解決了幾個持續存在的工程難題:
- 不再有 URL 膨脹: 複雜的篩選條件、類似資料庫的查詢語言,或深層圖形結構,移出 URI 字串,安全地放入請求主體。
- 預設隱私保護: 敏感的搜尋條件(如個人屬性、醫療篩選條件或專有搜尋參數)不再暴露於瀏覽器歷史記錄、中介代理記錄或伺服器存取記錄中。
-
內建效率: 因為
QUERY被明確宣告為可快取且安全,現代快取基礎設施可以像處理GET請求一樣對待它,並支援條件式請求(如在基礎資料集未變更時回傳304 Not Modified)。
架構模式:「等效資源」
伴隨資料密集查詢模式所引入的最優雅面向之一,是利用 Location 標頭的概念。
當用戶端傳送複雜的 QUERY 酬載時,伺服器不僅會回傳即時的 JSON 陣列。它也可以回應一個 Location 標頭,指向代表該特定查詢結果的暫存或永久資源識別碼。
HTTP/1.1 200 OK
Content-Type: application/json
Location: /api/searches/9f8c-4a1b-8e3d
Enter fullscreen mode Exit fullscreen mode
伺服器完成初始查詢的繁重工作後,後續的輪詢或分頁可以使用輕量級、標準的 GET 請求針對該 URI 執行。它在有狀態查詢執行與無狀態資源檢索之間搭起橋樑。
生產就緒與實作考量
雖然語意清晰度對後端架構來說是一大勝利,但推出全新的 HTTP 方法仍需謹慎的基礎設施規劃:
-
邊緣與代理過濾: 許多舊版 Web 應用程式防火牆(WAF)、企業防火牆與反向代理會硬編碼阻擋未識別的 HTTP 動詞。在公開 API 中採用
QUERY之前,請確認你的 API 閘道與邊緣基礎設施能妥善處理自訂方法,而非直接回傳405 Method Not Allowed。 -
快取金鑰產生: 傳統 CDN 僅使用請求路徑與查詢字串建立快取金鑰,完全忽略請求主體。如果你快取
QUERY回應時未自訂快取金鑰邏輯以包含請求主體的雜湊值,就可能導致嚴重的快取碰撞問題(User A 收到 User B 的搜尋結果)。 -
用戶端生態系統支援: 確保你的上游 HTTP 用戶端、行動網路函式庫,以及內部服務對服務的通訊工具,都支援在
QUERY動詞旁傳送請求主體。
展望未來
RFC 10008 的引入,為我們提供了一套更清晰的詞彙,用以建構資料密集、注重隱私且可擴展的系統。我們終於擁有了一等公民,可用來查詢資料,而無需濫用 POST 或將 GET 拉伸至其結構極限。
你在自己的技術堆疊中如何進行現代 API 設計?你是否計劃在即將到來的內部架構中評估 QUERY?歡迎在下方留言討論。👇
#WebDev #APIDesign #HTTP #SoftwareArchitecture #Backend #TechStandards
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.