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

本頁內容適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

本文提供使用 Apigee 開發 API Proxy 的最佳做法。

這裡涵蓋的主題包括設計、程式碼、政策使用、監控和偵錯。這些資訊是根據開發人員與 Apigee 合作,成功導入 API 計畫的經驗彙整而成。這份文件會隨著時間推移不斷更新。

除了本文的準則,您也可以參閱「反模式簡介」。

開發標準

註解和文件

  • ProxyEndpointTargetEndpoint 設定中提供內嵌註解。註解可提高流程的可讀性,特別是當政策檔案名稱不夠清楚,無法表達流程的基礎功能時。
  • 發布實用評論。避免使用明顯的註解。
  • 使用一致的縮排、間距、垂直對齊方式等。

架構樣式編碼

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

  • 為啟用 DRY (不要重複自己),政策設定和指令碼應盡可能實作可重複使用的專用函式。舉例來說,從要求訊息中擷取查詢參數的專屬政策可以稱為 ExtractVariables.ExtractRequestParameters
  • 從 API Proxy 中清除未使用的政策和資源 (JavaScript、Java、XSLT),特別是可能導致匯入和部署程序變慢的大型資源。

命名慣例

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

API Proxy 開發

初步設計注意事項

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

啟用 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 的要求或回應流程中,訊息酬載大小預設上限為 10MB。如需處理大型酬載,使用者可以在 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 Flow 中,使用 AssignMessage 政策建構錯誤回應,而非 RaiseFault 政策。根據發生的錯誤類型,有條件地執行 AssignMessage 政策。
  • 一律包含預設的「全方位」錯誤處理常式,以便將系統產生的錯誤對應至客戶定義的錯誤回應格式。
  • 如有可能,請務必讓錯誤回應符合貴公司或專案提供的任何標準格式。
  • 使用有意義且使用者可理解的錯誤訊息,建議解決錯誤狀況的方法。

請參閱「處理錯誤」。

持續性

鍵/值對應

  • 鍵/值對應僅適用於有限的資料集。不適合做為長期資料儲存空間。
  • 使用鍵/值對應時,請考量效能,因為這項資訊會儲存在 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> 元素中指定快取資源。

請參閱回應快取政策

政策和自訂程式碼

政策或自訂程式碼?

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

JavaScript

  • 如果 JavaScript 比 Apigee 政策更直覺易用,請使用 JavaScript (例如設定許多不同的 URI 組合時)。target.url
  • 複雜的酬載剖析作業,例如疊代 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 Proxy 資源資料夾。這樣做可縮短部署時間,並允許多個 API Proxy 參照相同的 JAR 檔案。另一個優點是類別載入器隔離。
  • 請勿使用 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 政策」。

記錄

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

請參閱訊息記錄政策

監控

雲端客戶不必檢查 Apigee 的個別元件 (路由器、訊息處理器等)。Apigee 全球營運團隊會全面監控所有元件,並根據客戶的健康狀態檢查要求,執行 API 健康狀態檢查。

Apigee 數據分析

Analytics 可提供非重大 API 監控,因為系統會測量錯誤百分比。

請參閱數據分析資訊主頁

偵錯

在 API 的開發或實際執行作業期間,Apigee 使用者介面中的追蹤工具有助於偵錯 API 執行階段問題。

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

安全性

API Proxy 中的自訂邏輯

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

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

政策 政策用途
JavaScript 和 PythonScript

使用時機:

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

不適用的情況:

  • Apigee 的 API 閘道不是應用程式伺服器 (也不會提供完整的 JavaScript 執行階段,例如 node.js)。如果每次處理呼叫都會超過一秒,則邏輯很可能不屬於閘道,而應是基礎服務的一部分。

最佳做法: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 Proxy 必須傳輸情境 (例如變數) 或接收來自外部實作的情境

總結來說:

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

下圖說明這個程序: