【API架構】REST API 設計的原則和實踐
這篇最佳實踐文章面向對創建 RESTful Web 服務感興趣的開發人員,這些服務提供跨多個服務套件的高可靠性和一致性;遵循這些準則;服務定位于內部和外部客戶快速、廣泛、公開采用。
這是一個完整的圖表,可以輕松理解 REST API 的原理、方法和最佳實踐。
現在,讓我們從每個盒子的原理開始詳細說明它。
六項原則/約束
客戶端-服務器:關注點分離是客戶端-服務器約束背后的原則。通過將用戶界面問題與數據存儲問題分開,我們提高了用戶界面跨多個平臺的可移植性,并通過簡化服務器組件提高了可擴展性。
無狀態:通信必須是無狀態的,如客戶端-無狀態-服務器 (CSS) 風格。從客戶端到服務器的每個請求都必須包含理解請求所需的所有信息。因此,會話狀態完全保留在客戶端上。
可緩存:為了提高網絡效率,我們添加了緩存約束以形成客戶端-緩存-無狀態-服務器風格。緩存約束要求數據響應帶有隱式或顯式標簽為可緩存或不可緩存的請求。如果響應是可緩存的,則客戶端緩存有權為以后的等效請求重用該響應數據。
分層系統:客戶端通常無法判斷它是直接連接到終端服務器還是沿途的中介。中間服務器可以通過啟用負載平衡和提供共享緩存來提高系統可擴展性。層也可以強制執行安全策略。
按需代碼:REST 允許通過下載和執行小程序或腳本形式的代碼來擴展客戶端功能。通過減少需要預先實現的功能數量來簡化客戶端。它允許在部署后下載功能,提高了系統的可擴展性。
統一接口:通過將通用性的軟件工程原理應用于組件接口,簡化了整個系統架構,提高了交互的可見性。實現與它們提供的服務分離,這鼓勵了獨立的可進化性。REST 定義了四個接口約束:資源的識別、通過表示的資源操作、自描述消息和作為應用程序狀態引擎的超媒體。
- 自描述消息:每條消息都包含足夠的信息來描述如何處理消息。
- 基于資源:在請求中使用 URI 作為資源標識符來標識單個資源。資源本身在概念上與返回給客戶端的表示分開。
- 通過表示操作資源:當客戶端表示資源(包括附加的任何元數據)時,它有足夠的信息來修改或刪除服務器上的資源,前提是它有這樣做的權限。
- 超媒體作為應用程序狀態引擎 (HATEOAS):客戶端通過正文內容、查詢字符串參數、請求標頭和請求的 URI(資源名稱)傳遞狀態。服務通過正文內容、響應代碼和響應頭向客戶端提供狀態。
最佳實踐
現在,讓我們換個角度來了解 REST 的基本最佳實踐,這是每個工程師都應該知道的。
- 保持簡單和細粒度:創建模擬系統底層應用程序域或系統數據庫架構的 API。最終,您將需要聚合服務——利用多種底層資源來減少閑聊的服務。
- 過濾和排序:對于大型數據集,從帶寬的角度來看,限制返回的數據量至關重要。此外,我們可能希望指定要包含在響應中的資源的字段或屬性,從而限制返回的數據量。我們最終想要查詢特定值并對返回的數據進行排序。
- 版本控制:有很多方法可以破壞合同并對 API 開發中的客戶產生負面影響。如果您不確定更改的后果,最好謹慎行事并考慮版本控制。在決定新版本是否合適或對現有表示的修改是否充分和可接受時,需要考慮幾個因素。由于維護多個版本變得繁瑣、復雜、容易出錯且成本高昂,因此對于任何給定資源,您應該支持不超過兩個版本。
- 緩存:緩存通過啟用系統中的層來消除檢索請求數據的遠程調用來增強可擴展性。服務通過在響應(如 Cache-Control、Expires、Pragma、Last-Modified 等)上設置標頭來提高緩存能力
- 分頁:REST 的原則之一是連通性——通過超媒體鏈接。同時,沒有它們,服務仍然有用。當鏈接在響應中返回時,API 變得更具自我描述性。對于支持分頁的響應中返回的集合,“first”、“last”、“next”和“prev”鏈接至少是有益的。
- 資源命名:當資源命名正確時,API 是直觀且易于使用的。做得不好,同樣的 API 會讓人感覺很笨拙,并且難以使用和理解。RESTful API 適用于消費者。URI 的名稱和結構應該向這些消費者傳達含義。通常很難知道數據邊界應該是什么,但是通過了解您的數據,您很可能有能力進行嘗試,并將什么作為代表返回給您的客戶是有意義的。為您的客戶設計,而不是為您的數據設計。
- - 復數:普遍接受的做法是始終在節點名稱中使用復數形式,以保持您的 API URI 在所有 HTTP 方法中保持一致。原因是“客戶”是服務套件中的一個集合,而 ID(例如 33245)指的是集合中的這些客戶之一。
- 監控:確保添加各種監控以提高 API 的質量或性能。數據點可以是響應時間(P50、p90、P99)、狀態代碼(5XX、4XX 等)、網絡帶寬等等。
- 安全:
- - 授權/認證:對服務的授權與對任何應用程序的授權沒有什么不同。問這個問題,“這個主體對給定資源是否有請求的權限?”
- - CORS:在服務器上實現 CORS 就像在響應中發送額外的 HTTP 標頭一樣簡單,例如 Access-Control-Allow-Origin、Access-Control-Allow-Credentials 等
- - TLS:所有身份驗證都應使用 SSL。OAuth2 需要授權服務器和訪問令牌憑據才能使用 TLS。
- - 冪等性:如果執行一次或多次,將產生相同結果的操作。根據其適用的上下文,它可能具有不同的含義。例如,在具有副作用的方法或子程序調用的情況下,這意味著修改后的狀態在第一次調用后保持不變。
- - 輸入驗證:驗證服務器上的所有輸入。接受“已知”好的輸入并拒絕錯誤的輸入,防止 SQL 和 NoSQL 注入,將消息大小限制為字段的確切長度,服務應僅顯示一般錯誤消息等等。
- - 限速:是一種限制網絡流量的策略。它限制了某人在特定時間范圍內重復操作的頻率 - 例如,嘗試登錄帳戶。
- - 記錄:確保您不會意外記錄任何個人身份信息 (PII)。
至此,我結束了這次學習,我希望你今天學到了一些新東西。
本文轉載自微信公眾號「超級架構師」,可以通過以下二維碼關注。轉載本文請聯系超級架構師公眾號。