HTTP API可演進性最佳實踐

正如標題所示,Benjamin Carlyle試圖在《Best Practices For HTTP API Evolvability》一文中爲圍繞HTTP API構建的系統的設計定義原則和實踐,這些系統是可擴展的,並且能一直進化下去。他先指出了REST(一種架構風格)和HTTP API(通過HTTP暴露的編程接口)之間的區別。

HTTP API是針對一個特定服務的面向開發者的接口,也被稱爲RESTful服務契約面向資源架構URI Space

我說REST和HTTP API緊密相關是因爲大多數HTTP API並不嚴格遵守統一接口約束,嚴格說來統一接口約束要求接口是“標準的”[…]

文章開頭他標識出了API設計中的不同元素,這些元素決定了API後續的進化。通常來說,API進化涉及到了設計客戶端與服務器的兼容性;特別是API的向後和向前兼容變更。 變更頻率按增序排列依次是:

  1. API中用到的方法的通用語義,包含異常條件和其他元數據
  2. API中用到的媒體類型的通用語義,包含全部Schema信息
  3. 構成API的URI集合,包含API中用到的每個通用方法和媒體類型的特定語義

API進化中改變最少的就是方法的語義。文中描述的最佳實踐是識別出向前和向後兼容的變化,運用Postel法則讓服務與客戶端以一種更能容忍的方式進行進化。他建議儘可能地使用HTTP錯誤碼來傳達兼容性問題。

最佳實踐3:新方法名應該選擇那些不會和任何已有方法發生向前兼容的名字。例如,如果要處理的方法必須正確理解(必須理解語義)方法的新特性,那麼應該選擇一個新的方法名。

最佳實踐4:服務應該忽略它們不理解的標頭或組件。代理應該不加修改地傳遞這些標頭,或者是無法理解的組件。

[…]

最佳實踐7:在某個數字範圍內爲新狀態分配一個狀態碼,這個範圍可以粗粒度地標識已存在的條件。

[…]

最佳實踐9:如果新狀態是一個已知狀態(除了400 Bad Request或500 Internal Server Error)的子集,可以向響應頭添加信息來細化已知狀態的含義,而不是分配一個新的狀態碼。

他指出了一個重要的區別,即客戶端與服務器交互中媒體類型的對稱本質。

[…]與客戶端和服務器之間非對稱的方法和狀態不同,媒體類型通常能用作請求或響應的負載,即適用於兩個方向。爲此本節中我們不討論客戶端與服務器,而是講發送端與接收端。

...這構成了與媒體類型相關的最佳實踐的基礎

[…]

最佳實踐11:只有當驗證邏輯是爲與文檔發送方相同版本或後續版本的API編寫的情況下,纔可能出現不符合最佳實踐10的文檔驗證。

最佳實踐12:在不違反媒體類型設計目標的前提下,如果能向現有媒體類型的Schema中添加新信息,那麼就添加吧。

他提倡使用Content-Types和Accept標頭來管理髮送端與接收端之間的兼容性。

HTTP API習慣於做出向後不兼容的媒體類型Schema變更。新客戶端請求或者提供了Schema中帶有向後不兼容變更的新媒體類型。老的客戶端繼續請求或提供舊的媒體類型。直到所有重要的相關實現都升級到最新的媒體類型集之前,客戶端與服務器端都應該要支持舊的媒體類型。

他認爲對資源的修改,尤其是URI的修改都是服務器應該關心的事;如果客戶端是設計成由超媒體約束驅動的話,一般這些修改都不應該引入兼容性問題。他提倡使用Cookies將客戶端請求路由到合適的服務實例/服務器。

在使用多種通用方法時,我們不再處理通用的方法或媒體類型,而是和帶有特定語義的特定URL打交道。[…]在考慮如下服務契約時,我傾向於採用以服務器爲中心的視角:

  • GET /invoice/{invoice-id},返回媒體類型application/invoice+xml,內容是invoice-id指定的發貨單
  • GET /invoice/{invoice-id}/paid,返回媒體類型text/plain(xsd:bool語法),內容是invoice-id指定的發貨單的支付狀態
  • PUT /invoice/{invoice-id}/paid,接受媒體類型text/plain(xsd:bool語法),設置invoice-id指定的發貨單的支付狀態

此外,他還提出了一些客戶端的最佳實踐,以便客戶端能應對服務器URI的轉變(transition)和進化。

最佳實踐19:在升級時,服務應該通過Cookies追蹤哪些客戶端應該連接到舊的服務器,哪些應該連接到新的服務器,或者也可以使用類似的機制。

最佳實踐20:即使不是在響應HEAD或GET請求,客戶端也應該遵從服務器發回的重定向狀態響應[說明:RFC2616]

最佳實踐21:重新設計URL時,確保新的URL擁有和舊URL一樣的語義,並將舊URL重定向到新的URL上。

本文中提供了一些基本原理,讓HTTP API系統能隨着時間不斷進化。請務必閱讀Benjamin Carlyle的完整原文以便對這一主題能有更深入的理解。

查看英文原文:Best Practices For HTTP API Evolvability

發佈了19 篇原創文章 · 獲贊 7 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章