使用 Apigee 設計及開發 API Proxy 的最佳做法

本頁適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

本文提供一套最佳做法,說明如何使用 Apigee 開發 API Proxy。

本課程涵蓋的主題包括設計、程式設計、政策使用、監控和偵錯。這些資訊是透過與 Apigee 合作的開發人員在導入成功 API 計畫時所累積的經驗所彙整而成。此文件會不斷修訂,與時俱進。

除了這裡的規範外,您可能也會覺得反模式簡介很實用。

開發標準

註解和文件

  • ProxyEndpointTargetEndpoint 設定中提供內嵌註解。註解可提升資料流的可讀性,尤其是在政策檔案名稱無法充分描述資料流的基礎功能時。
  • 發布實用的評論。避免使用明顯的註解。
  • 使用一致的縮排、間距、垂直對齊方式等。

架構式程式碼

架構式程式碼會將 API 代理資源儲存在您自己的版本管控系統中,以便在各個本機開發環境中重複使用。舉例來說,如要重複使用政策,請將政策儲存在來源控管中,方便開發人員同步處理並在自己的 Proxy 開發環境中使用。

  • 為啟用 DRY (Don't Repeat Yourself),政策設定和指令碼應盡可能實作專屬的可重複使用函式。舉例來說,您可以呼叫 ExtractVariables.ExtractRequestParameters,這是用於從要求訊息中擷取查詢參數的專屬政策。
  • 從 API 代理程式中清除未使用的政策和資源 (JavaScript、Java、XSLT),特別是可能會減緩匯入和部署程序的大型資源。

命名慣例

  • 政策 name 屬性和 XML 政策檔案名稱必須相同。
  • 指令碼和 ServiceCallout 政策政策 name 屬性,以及資源檔案的名稱應相同。
  • DisplayName 應向從未使用過該 API Proxy 的使用者,如實說明政策的功能。
  • 請根據政策的用途命名。Apigee 建議您為政策建立一致的命名慣例。例如,使用簡短的前置字串,後面接著以破折號分隔的描述性字詞序列。例如,AssignMessage 政策AM-xxx。另請參閱 apigeelint 工具
  • 請為資源檔案使用適當的副檔名,例如 JavaScript 的 .js、Python 的 .py,以及 Java JAR 檔案的 .jar
  • 變數名稱應保持一致。如果您選擇了 camelCase 或 under_score 等樣式,請在整個 API 代理程式中使用該樣式。
  • 盡可能使用變數前置字元,依據變數用途進行分類,例如 Consumer.usernameConsumer.password

API Proxy 開發

初步設計考量

  • 如需 RESTful API 設計指南,請下載電子書《 Web API Design: The Missing Link》。
  • 盡可能利用 Apigee 政策和功能建構 API 代理程式。請勿在 JavaScript、Java 或 Python 資源中編寫所有 Proxy 邏輯。
  • 以有條理的方式建構流程。建議使用多個流程 (每個流程各有一個條件),而非在同一個預流程和後置流程中加入多個條件式附件。
  • 做為「安全防護機制」,請建立預設 API Proxy,其 ProxyEndpoint BasePath 為 /。這項功能可用於將基本 API 要求重新導向至開發人員網站、傳回自訂回應,或執行比傳回預設 messaging.adaptors.http.flow.ApplicationNotFound 更實用的其他動作。
  • 為獲得最佳效能,Apigee 建議每個 Apigee 環境或環境群組使用 API 代理程式 basepath 數量不超過 3,000 個。如果超過這個建議值,所有新的和現有的 API 代理程式部署作業都會延遲。
  • 使用 TargetServer 資源,將 TargetEndpoint 設定與具體網址分離,以便在各環境中進行宣傳。
    請參閱「跨後端伺服器負載平衡」。
  • 如果您有多個 RouteRule,請建立一個「預設」RouteRule,也就是沒有條件的 RouteRule。請確認預設 RouteRule 是在條件式路由清單的最後定義。ProxyEndpoint 會由上往下評估 RouteRules。請參閱「API Proxy 設定參考資料」。
  • API 代理程式套件大小:API 代理程式套件的大小不得超過 15 MB。
  • API 版本管理:如要瞭解 Apigee 對 API 版本管理的想法和建議,請參閱 《Web API Design: The Missing Link》電子書中的「Versioning」

啟用 CORS

在發布 API 之前,您必須將 CORS 政策新增至 ProxyEndpoint 的要求 PreFlow,以支援用戶端跨來源要求。

CORS (跨源資源共享) 是一種標準機制,可讓您在網頁中執行 JavaScript XMLHttpRequest (XHR) 呼叫,以便與非來源網域的資源互動。所有瀏覽器都會強制執行同源政策,而 CORS 是常見的實作解決方案。舉例來說,如果您透過在瀏覽器中執行的 JavaScript 程式碼,對 Twitter API 發出 XHR 呼叫,該呼叫將會失敗。這是因為向瀏覽器提供網頁的網域與提供 Twitter API 的網域不同。CORS 為此問題提供瞭解決方案,只要伺服器希望提供跨來源資源共用功能,即可選擇加入

如要瞭解如何在發布 API 前,在 API Proxy 中啟用 CORS,請參閱「為 API Proxy 新增 CORS 支援」。

郵件酬載大小

預設,Apigee 要求或回應流程中的訊息酬載大小限制為 10 MB。如果您需要處理大量酬載,可以使用 API Proxy 的 ProxyEndpointTargetEndpoint 設定中的 <Properties> 元素,設定更高的上限。

如要進一步瞭解如何使用 response.payload.parse.limitrequest.payload.parse.limit 屬性,為要求或回應流程設定最大酬載大小 (上限為 30 MB),請參閱 API Proxy 設定參考資料

請注意,如果超過指定的訊息大小,就會導致 protocol.http.TooBigBody 錯誤。

請考慮採用下列建議策略,在 Apigee 中處理大型訊息:

  • 強烈建議您將經常處理大型酬載的 API 代理程式隔離在專用環境中,以免發生潛在的「鄰居干擾」情況。管理大型酬載的 Proxy 會大量消耗系統 CPU 和記憶體資源,尤其是與與大型酬載互動的政策搭配使用時。
  • 我們也建議您限制政策的使用方式,以便與大型酬載互動。使用政策反覆剖析及複製要求或回應酬載,可能會對系統效能造成負面影響。
  • 我們建議處理大量高酬載要求的機構提供額外的 IP 位址,以免因水平調整而導致連接埠用盡。
  • 請考慮使用串流要求和回應。請注意,在您進行串流時,政策就無法再存取訊息內容。請參閱「串流要求和回應」。
  • 如果貴機構採用按使用付費,建議您只針對在 Comprehensive 環境中部署的 API Proxy 使用可設定的大型酬載限制

錯誤處理

  • 利用 FaultRules 處理所有錯誤。(RaiseFault 政策用於停止訊息流程,並將處理作業傳送至 FaultRules 流程)。
  • 在 FaultRules 流程中,請使用 AssignMessage 政策建立錯誤回應,而非 RaiseFault 政策。根據發生的錯誤類型,有條件地執行 AssignMessage 政策。
  • 一律包含預設的「catch-all」錯誤處理程序,以便將系統產生的錯誤對應至客戶定義的錯誤回應格式。
  • 盡可能讓錯誤回應符合貴公司或專案中可用的任何標準格式。
  • 使用有意義且使用者可理解的錯誤訊息,建議錯誤情況的解決方案。

請參閱「處理錯誤」。

持續性

鍵/值對應

  • 請只針對有限的資料集使用鍵/值對應。並非用來長期儲存資料。
  • 使用鍵/值對應時,請考量效能,因為這類資訊會儲存在 Cassandra 資料庫中。

請參閱 KeyValueMapOperations 政策

回應快取

  • 如果回應失敗,或要求不是 GET,請勿填入回應快取。請勿快取建立、更新和刪除作業。<SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • 使用單一一致的內容類型 (例如 XML 或 JSON) 填入快取。擷取 responseCache 項目後,請使用 JSONtoXML 或 XMLToJSON 轉換為所需的內容類型。這樣一來,系統就不會儲存兩筆、三筆或更多筆資料。
  • 請確認快取鍵符合快取需求。在許多情況下,request.querystring 可做為專屬 ID。
  • 除非明確要求,否則請勿在快取索引鍵中加入 API 金鑰 (client_id)。大多數情況下,僅透過金鑰加以保護的 API 會針對特定要求,向所有用戶端傳回相同的資料。根據 API 金鑰為多個項目儲存相同值的做法效率不高。
  • 設定適當的快取到期間隔,避免髒讀。
  • 盡可能讓回應快取政策在 ProxyEndpoint 回應 PostFlow 中盡可能晚執行,以便填入快取。也就是說,請在轉譯和中介服務步驟後執行,包括以 JavaScript 為基礎的中介服務,以及 JSON 和 XML 之間的轉換。快取經仲介的資料,可避免每次擷取快取資料時執行仲介步驟而產生的效能成本。

    請注意,如果中介服務導致每個請求的回應不同,您可能會想改為快取未經中介服務的資料。

  • 用於查詢快取項目的回應快取政策應在 ProxyEndpoint 要求的 PreFlow 中執行。在傳回快取項目之前,請避免實作太多邏輯 (除了快取鍵產生)。否則,快取的效益將降到最低。
  • 一般來說,您應盡可能讓回應快取查詢與用戶端要求保持一致。相反地,您應盡可能讓回應快取填入作業與用戶端回應保持一致。
  • 在 Proxy 中使用多個不同的回應快取政策時,請遵循下列指南,確保每個政策的行為皆不重複:
    • 根據互斥的條件執行各項政策。這有助於確保只有一個回應快取政策執行。
    • 為每項回應快取政策定義不同的快取資源。您可以在政策的 <CacheResource> 元素中指定快取資源。

請參閱「ResponseCache 政策」。

政策和自訂程式碼

政策或自訂程式碼?

  • 請盡可能優先使用內建政策。Apigee 政策經過強化、最佳化,並提供支援。舉例來說,請使用標準的 AssignMessage 政策ExtractVariables 政策,而非 JavaScript (盡可能) 來建立酬載、從酬載中擷取資訊 (XPath、JSONPath) 等等。
  • 建議使用 JavaScript 而非 Python 和 Java。不過,如果效能是主要需求,建議您使用 Java 而非 JavaScript。

JavaScript

  • 如果 JavaScript 比 Apigee 政策更直覺 (例如為許多不同的 URI 組合設定 target.url),請使用 JavaScript。
  • 複雜的酬載剖析作業,例如透過 JSON 物件和 Base64 編碼/解碼進行迴迭。
  • JavaScript 政策設有時間限制,因此會封鎖無限迴圈。
  • 請一律使用 JavaScript 步驟,並將檔案放在 jsc 資源資料夾中。JavaScript 政策類型會在部署時預先編譯程式碼。

Java

  • 如果效能是優先考量,或是邏輯無法在 JavaScript 中實作,請使用 Java。
  • 在原始碼追蹤中加入 Java 來源檔案。

如要瞭解如何在 API Proxy 中使用 Java,請參閱 JavaCallout 政策

Python

  • 除非絕對必要,否則請勿使用 Python。Python 指令碼會在執行階段進行解譯,因此可能會導致簡單執行作業的效能瓶頸。

指令碼呼叫 (Java、JavaScript、Python)

  • 使用全域 try/catch 或等效方法。
  • 擲回有意義的例外狀況,並妥善擷取這些例外狀況,以便在錯誤回應中使用。
  • 提早擲回及擷取例外狀況。請勿使用全域 try/catch 來處理所有例外狀況。
  • 視需要執行空值和未定義的檢查。例如擷取選用的工作流程變數時。
  • 請勿在指派的程式碼中發出 HTTP/S 要求。請改用 ServiceCallout 政策,因為這項政策可妥善處理連線。

JavaScript

  • API 平台上的 JavaScript 會透過 E4X 支援 XML。

請參閱「JavaScript 物件模型」。

Java

  • 存取訊息酬載時,請盡量使用 context.getMessage() 而非 context.getResponseMessagecontext.getRequestMessage。這可確保程式碼能在要求和回應流程中擷取酬載。
  • 將程式庫匯入 Apigee 機構或環境,且不要將這些程式庫納入 JAR 檔案。這麼做可縮減套件大小,並讓其他 JAR 檔案存取相同的程式庫存放區。
  • 請使用 Apigee 資源 API 匯入 JAR 檔案,而不是將這些檔案納入 API 代理資源資料夾中。這麼做可縮短部署時間,並讓同一個 JAR 檔案可供多個 API 代理程式參照。另一個優點是類別載入器隔離。
  • 請勿使用 Java 處理資源 (例如建立及管理執行緒集區)。

Python

  • 擲回有意義的例外狀況,並妥善擷取這些例外狀況,以便在 Apigee 錯誤回應中使用

請參閱 PythonScript 政策

ServiceCallouts

  • 使用 Proxy 鏈結的用途非常多,例如在一個 API Proxy 中使用服務呼叫來呼叫另一個 API Proxy。如果您使用 Proxy 鏈結,請務必避免無限迴圈遞迴的回呼,以免回到同一個 API Proxy。

    如果您要連結同一個機構和環境中的 Proxy,請務必參閱「將 API Proxy 連結在一起」一文,進一步瞭解如何實作本地連線,以免產生不必要的網路開銷。

  • 使用 AssignMessage 政策建構 ServiceCallout 要求訊息,並在訊息變數中填入要求物件。(包括設定要求酬載、路徑和方法)。
  • 政策中設定的網址需要通訊協定規格,也就是說,網址的通訊協定部分 (例如 https://) 無法透過變數指定。此外,您必須為網址的網域部分和網址的其餘部分使用不同的變數。例如:https://example.com
  • 請將 ServiceCallout 的回應物件儲存在個別訊息變數中。接著,您可以剖析訊息變數,並完整保留原始訊息酬載,供其他政策使用。

請參閱服務標示政策

存取實體

AccessEntity 政策

  • 為提升成效,請使用 uuid 而非應用程式名稱來查詢應用程式。

請參閱「AccessEntity 政策」。

記錄

  • 在各個套件之間和同一套件內使用通用的 syslog 政策。這樣就能維持一致的記錄格式。

請參閱訊息記錄政策

監控

Cloud 客戶不需要檢查 Apigee 的個別元件 (路由器、訊息處理器等)。根據客戶的健康狀態檢查要求,Apigee 的全球營運團隊會徹底監控所有元件,以及 API 健康狀態檢查。

Apigee Analytics

當 Analytics 評估錯誤百分比時,可以提供非重大的 API 監控功能。

請參閱「Google Analytics 資訊主頁」一文。

偵錯

在 API 的開發或實際運作期間,Apigee UI 中的追蹤記錄工具可用於偵錯執行階段 API 問題。

請參閱「使用偵錯工具」。

安全性

API Proxy 中的自訂邏輯

建構 API Proxy 時,常見的要求是加入一些處理要求和/或回應的邏輯。雖然許多需求可透過預先定義的步驟/動作/政策來滿足,例如驗證權杖、套用配額或以快取物件回應,但通常仍需要使用可程式化功能。舉例來說,您可以根據要求中找到的鍵,從路由表中查詢位置 (端點),然後動態套用目標端點或自訂/專屬驗證方法等。

Apigee 為開發人員提供多種選項,以便處理這類自訂邏輯。本文件將探討這些選項,以及何時使用這些選項:

政策 政策用途
JavaScript 和 PythonScript

使用時機:

  • JavaScript 和 PythonScript 政策的功能相同。開發人員通常會根據自己熟悉的語言,決定採用哪一種語言。
  • JavaScript 和 PythonScript 政策最適合用於處理不太複雜且不需要使用第三方程式庫的內嵌邏輯。
  • 這些政策的效能不如 JavaCallout 政策。

不適用的情況:

  • Apigee 的 API 閘道並非應用程式伺服器 (也不提供 node.js 等完整的 JavaScript 執行階段)。如果呼叫需要超過一秒的時間才能處理,則邏輯很可能不屬於閘道,而應屬於基礎服務的一部分。

最佳做法:Apigee 建議使用 JavaScript 而非 PythonScript,因為 JavaScript 的效能較佳。

JavaCallout

使用時機:

  • 處理內嵌邏輯的效能至關重要。
  • 現有的 Java 程式庫提供大部分邏輯。

不適用的情況:

  • Apigee 的 API 網關並非應用程式伺服器,也不會載入 Spring、JEE 等架構。如果呼叫通常需要超過一秒的時間才能處理,則可將邏輯視為功能性 (業務邏輯)。建議將其外部化為服務。
  • 為保護 Apigee API 閘道免於遭到濫用,系統會對可執行的程式碼類型設下限制。舉例來說,如果 Java 程式碼嘗試存取特定加密程式庫或存取檔案系統,就會遭到執行封鎖。
  • Java 應用程式 (尤其是仰賴第三方程式庫的應用程式) 可能會產生許多 (且大型) JAR 檔案。這可能會導致閘道啟動時間變慢。
ExternalCallout

使用時機:

  • 非常適合將自訂邏輯外部化,並允許自訂邏輯存取 (並視需要修改) 訊息內容。
  • 外部插入式文字會實作 gRPC,可能比 ServiceCallout 更有效率。
  • 在 Google Cloud 上使用 Apigee 或 Apigee hybrid 時,請考慮使用 Cloud Functions 或 Cloud Run 代管這類邏輯。
  • 可有效取代 Apigee Edge 中的代管目標功能。

不適用的情況:

  • 針對可快速執行的輕量邏輯,可在內文中執行。
ServiceCallout

使用時機:

  • 複雜的邏輯最好在閘道外實作。這項邏輯可擁有自己的生命週期 (版本和版本管理),且不會影響閘道的運作。
  • 當 REST/SOAP/GraphQL 端點已存在或可輕鬆實作時
  • 在 Google Cloud 上使用 Apigee 或 Apigee hybrid 時,建議您使用 Cloud Functions 或 Cloud Run 來代管這類邏輯。
  • 可有效取代 Apigee Edge 中的代管目標功能。

不適用的情況:

  • 針對可快速執行的輕量邏輯,在內文中
  • API 代理程式必須轉移情境 (例如變數),或從外部實作項目接收情境

總結來說:

  1. 如果邏輯簡單或瑣碎,請使用 JavaScript (建議) 或 PythonScript。
  2. 如果內嵌邏輯需要比 JavaScript 或 PythonScript 更佳的效能,請使用 JavaCallout。
  3. 如果邏輯必須外部化,請使用 ExternalCallout。
  4. 如果您已實作外部功能,且/或開發人員熟悉 REST,請使用 ServiceCallout。

下圖說明此程序: