模式: API網關
上下文
讓我們假設您正在構建一個使用Microservice體系結構模式的在線商店,並且您正在實現產品詳細信息頁面。您需要開發產品詳細信息用戶界面的多個版本:
- 用於桌面和移動瀏覽器的基於HTML5 / JavaScript的UI - HTML由服務器端Web應用程序生成
- 原生Android和iPhone客戶端 - 這些客戶端通過REST API與服務器交互
此外,在線商店必須通過REST API公開產品詳細信息,以供第三方應用程序使用。
產品詳細信息UI可以顯示有關產品的大量信息。例如,POJO in Action的Amazon.com詳細信息頁面顯示:
- 有關該書的基本信息,如標題,作者,價格等。
- 本店的購買歷史
- 可用性
- 購買選項此書經常購買的其他商品
- 購買此書的顧客
- 購買的其他商品
- 顧客評論
- 賣家排名
- ...
由於在線商店使用微服務架構模式,因此產品詳細信息數據分布在多個服務上。例如,
- 產品信息服務 - 產品的基本信息,如標題,作者定價服務
- 產品價格訂購服務
- 產品購買歷史庫存服務
- 產品可用性評估服務
- 客戶評論...
因此,顯示產品詳細信息的代碼需要從所有這些服務中獲取信息。
問題
基於微服務的應用程序的客戶端如何訪問各個服務?
關注點
-
微服務提供的API的粒度通常與客戶端所需的不同。微服務通常提供細粒度的API,這意味着客戶端需要與多個服務進行交互。例如,如上所述,需要產品細節的客戶端需要從眾多服務中獲取數據。
-
不同客戶需要不同的數據。例如,產品詳細信息頁面桌面的桌面瀏覽器版本通常比移動版本更精細。
-
不同類型的客戶端的網絡性能不同。例如,移動網絡通常比非移動網絡慢得多且具有更高的延遲。當然,任何WAN都比LAN快得多。這意味着本機移動客戶端使用的網絡與服務器端Web應用程序使用的LAN具有非常不同的性能特征。服務器端Web應用程序可以對后端服務發出多個請求,而不會影響用戶體驗,因為移動客戶端只能做一些。
-
服務實例的數量及其位置(主機+端口)動態變化
-
對服務的分區可能會隨着時間的推移而發生變化,應該從客戶端隱藏
-
服務可能使用各種協議,其中一些協議可能不適合Web
解決方案
實現API網關,它是所有客戶端的單一入口點。API網關以兩種方式之一處理請求。有些請求只是代理/路由到適當的服務。它通過扇出多個服務來處理其他請求。
API網關可以為每個客戶端公開不同的API,而不是提供一個通用的樣式API。例如,Netflix API網關運行特定於客戶端的適配器代碼,該代碼為每個客戶端提供最適合其要求的API。
API網關也可以實現安全性,例如驗證客戶端是否有權執行請求
變種
此模式的變體是前端模式的后端。它為每種客戶端定義了一個單獨的API網關。
在此示例中,有三種客戶端:Web應用程序,移動應用程序和外部第三方應用程序。有三種不同的API網關。每個都為其客戶提供API。
例子
- Netflix API gateway
- A simple Java/Spring API gateway from the Money Transfer example application.
結果
使用API網關具有以下好處:
- 將客戶端與應用程序分區為微服務的方式隔離,使客戶端免於確定服務實例位置的問題為每個客戶端提供最佳API減少請求/往返次數。例如,API網關使客戶端能夠通過單次往返從多個服務中檢索數據。
- 更少的請求也意味着更少的開銷並改善用戶體驗。
- API網關對於移動應用程序至關重要。通過將用於調用多個服務的邏輯從客戶端移動到API網關來簡化客戶端從“標准”公共Web友好API協議轉換為內部使用的任何協議
API網關模式有一些缺點:
- 復雜性增加 - API網關是必須開發,部署和管理的另一個移動部分由於通過API網關額外的網絡跳躍而增加了響應時間 - 但是,對於大多數應用程序而言,額外往返的成本是微不足道的。
問題:
- 如何實現API網關?事件驅動/被動方法最好是必須按比例擴展以處理高負載。在JVM上,基於NIO的庫(如Netty,Spring Reactor等)是有意義的。NodeJS是另一種選擇。
相關的例子
- 微服務架構模式產生了對這種模式的需求。
- API網關必須使用客戶端發現模式或服務器端發現模式將請求路由到可用服務實例。
- API網關可以對用戶進行身份驗證,並將包含用戶信息的訪問令牌傳遞給服務
- API網關將使用Circuit Breaker來調用服務
- API網關通常實現API組合模式