只用 POST?讓我們結束這場荒謬的 API 設計辯論
揭穿 "只用 POST" 的 API 迷思,解釋其源於對 API 設計原則的誤解,並闡明 RESTful 和 RPC 架構風格的適用案例。
最近,有關是否應該設計 "只用 POST" 的 API 的討論引起了我的注意。深入了解這場辯論後,我發現人們爭論的問題不僅沒什麼意義,還暴露了許多開發者對 API 設計本質的誤解。今天,讓我們深入探討 API 設計的核心思想,看看為什麼這場辯論根本不應該存在。
"只用 POST" 的誤解
那些主張用 "只用 POST" 來取代 RESTful API 規範的開發者顯然沒有掌握 API 設計的最重要點。他們的論點通常包括:
- 簡化設計:一種方法可以處理所有事情
- 安全性:POST 參數不會出現在 URL 中
- 靈活性:POST 可以發送任何數據結構
乍一看,這些論點似乎有些道理。但事實上,這種觀點混淆了 HTTP 方法的選擇和 API 設計風格,這是兩個不同層次的問題。POST 僅是 HTTP 協議的一種方法,而 REST 是一種 API 設計風格。
API 設計的本質
在討論具體 API 風格之前,我們需要了解 API 設計的核心目的。好的 API 應該是:
- 清晰且易於理解:其他開發者(包括你未來的自己)應該能直觀地理解每個端點的用途。
- 一致性:遵循某些規範以減少學習成本。
- 可擴展:能夠輕鬆地進行版本控制和功能擴展。
- 高效:考慮性能和資源利用方面的效率。
RESTful API:不僅僅是 HTTP 方法的選擇
RESTful API 只是眾多 API 設計風格之一,重點在於資源和資源上的操作。讓我們以一個簡單的博客系統為例,看看 RESTful API 是如何設計的:
-
獲取所有文章:
-
獲取特定文章:
-
創建新文章:
-
更新文章:
-
刪除文章:
在這個例子中,我們可以看到:
- API 是圍繞 "文章" 資源設計的。
- 不同的 HTTP 方法用於表示不同的操作。
- URL 結構清晰,指示了被操作的資源。
這種設計方法使 API 更具直觀性和自描述性,讓開發者容易理解每個端點的功能。
RPC:理解 "只用 POST" 背後的 API 風格
RPC(遠程程序調用)風格 API 設計的目的是使遠程服務調用看起來像是本地函數的調用。
有趣的是,那些主張 "只用 POST" 的人可能沒有意識到他們實際上是在描述 RPC 風格。
相比於 RESTful API,RPC 更注重操作本身而非資源。因此,RPC 風格的 API 通常使用 "動詞+名詞" 的形式,例如 getProduct(productId)
或 createUser(userData)
。
在許多 RPC 實現中,所有操作通常通過 POST 請求發送到同一端點,並在請求正文中指定具體的操作和參數。這就是為什麼 "只用 POST" 的想法實際上比 REST 更接近 RPC。
例如,基於 HTTP 的 RPC 風格的 "獲取產品" 請求可能如下所示:
現代 RPC 框架,例如 gRPC,提供了更強大和高效的實現。讓我們用這個例子來展示 RPC 風格:
首先,我們定義服務和消息格式(使用 Protocol Buffers):
然後,在 Node.js 客户端中使用此服務就像調用一個本地函數一樣簡單:
在這個 RPC 風格的例子中,我們可以看到:
- 服務定義清楚列出了所有可用的操作(在此簡化例中為
GetArticle
和CreateArticle
)。 - 每個操作都有明確定義的請求和響應類型。
- 客户端代碼看起來像是在調用本地異步函數,使用
await
來等待結果,進一步隱藏了網絡通信的複雜性。 - 不需要手動構建 HTTP 請求或解析 JSON 響應。
雖然底層仍然可能使用 HTTP/2 作為傳輸協議,但 RPC 框架(如 gRPC)為開發者提供了一個抽象層,使得遠程調用看起來像本地函數調用。
因此,我們可以看到,大多數有關 "只用 POST" 和 RESTful API 的爭論本質上應該是關於這兩種 API 風格的討論:REST 和 RPC。然而,關鍵在於認識到這兩種風格各自有其適用的場景,選擇應基於項目的具體需求,而不是個人偏好。
REST vs RPC:沒有絕對的優劣之分
現在我們了解了 REST 和 RPC 之間的區別,讓我們看看它們各自的適用場景:
- REST 適合:
- 資源導向的應用(如內容管理系統、博客平台、電子商務網站)
- 需要良好緩存支持的場景(GET 請求自然可被緩存)
- 希望利用 HTTP 語義的項目(如使用適當的狀態碼)
- 需要良好可發現性和自描述性的面向公眾的 API
- RPC 適合:
- 行動導向的應用(如複雜數據處理操作、工作流程控制)
- 需要高性能和低延遲的系統(如實時交易系統)
- 內部微服務之間的通信(可能需要更靈活的參數傳遞)
- 當操作不能簡單映射到 CRUD(創建、讀取、更新、刪除)操作時
風格的選擇應基於你的具體需求。在某些情況下,你甚至可以在同一系統中混合使用這兩種風格,以滿足不同部分的需求。
結論
- API 設計的核心在於清晰性、一致性、可擴展性和效率,而不是堅持某種特定的方法或風格。
- RESTful 和 RPC 都是成熟的 API 設計範式。兩者之間的選擇應基於項目需求,而不是個人偏好。
- 如果你決定使用 "只用 POST",那麼請根據 RPC 風格設計你的 API。就像 RESTful 一樣,它是業界常用的 API 規範,但應在適合的情境中使用。
- 不要被表面的技術細節混淆。真正重要的是你的 API 能否有效地服務於用戶和業務需求。
- 在設計 API 時,花更多時間考慮你的資源模型、業務邏輯和用戶需求,而不是執著於使用哪種 HTTP 方法。
讓我們把注意力從這些無謂的爭論轉移開,專注於設計真正優秀的 API。畢竟,技術是用來解決問題的,而不是製造問題的。