您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件。 資訊
Apigee Edge 中的 JavaScript 政策可讓您新增自訂程式碼,並在 API Proxy 流程環境內執行。舉例來說,JavaScript 政策中的自訂程式碼可用於:
- 取得並設定流程變數
- 執行自訂邏輯並執行錯誤處理
- 從要求或回應擷取資料
- 動態編輯後端目標網址
- 以動態方式新增或移除要求或回應的標頭
- 剖析 JSON 回應
HTTP 用戶端
JavaScript 政策的一項強大功能是 HTTP 用戶端。HTTP 用戶端 (或 httpClient
物件) 可用來對後端或外部服務進行一或多項呼叫。如果您需要呼叫多個外部服務,並將回應混搭在單一 API 中,HTTP 用戶端特別實用。
使用 httpClient 物件呼叫後端的 JavaScript 程式碼範例
var headers = {'X-SOME-HEADER' : 'some value' }; var myRequest = new Request("http://www.example.com","GET",headers); var exchange = httpClient.send(myRequest);
httpClient
物件會公開兩種方法 get
和 send
(在上述程式碼範例中使用 send
) 發出 HTTP 要求。這兩種方法都是非同步的,會在實際 HTTP 要求完成前傳回 exchange
物件。
HTTP 要求可能需要幾秒鐘至幾分鐘的時間。發出 HTTP 要求後,請務必知道要求完成的時間,這樣才能處理要求的回應。判斷 HTTP 要求何時完成的最常見方法之一,就是叫用 exchange
物件的 waitForComplete()
方法。
waitForComplete()
waitForComplete()
方法會暫停執行緒,直到 HTTP 要求完成且傳回回應 (成功/失敗)。接著,系統就能處理後端或外部服務的回應。
含 waitForComplete() 的 JavaScript 程式碼範例
var headers = {'X-SOME-HEADER' : 'some value' }; var myRequest = new Request("http://www.example.com","GET",headers); var exchange = httpClient.send(myRequest); // Wait for the asynchronous GET request to finish exchange.waitForComplete(); // Get and Process the response if (exchange.isSuccess()) { var responseObj = exchange.getResponse().content.asJSON; return responseObj.access_token; } else if (exchange.isError()) { throw new Error(exchange.getError()); }
反模式
在 JavaScript 程式碼中傳送 HTTP 要求後,使用 waitForComplete()
會對效能產生影響。
請考量以下 JavaScript 程式碼,在傳送 HTTP 要求後呼叫 waitForComplete()
。
sample.js 的程式碼
// Send the HTTP request var exchangeObj = httpClient.get("http://example.com"); // Wait until the request is completed exchangeObj.waitForComplete(); // Check if the request was successful if (exchangeObj.isSuccess()) { response = exchangeObj.getResponse(); context.setVariable('example.status', response1.status); } else { error = exchangeObj.getError(); context.setVariable('example.error', 'Woops: ' + error); }
在這個例子中:
- JavaScript 程式碼將 HTTP 要求傳送至後端 API。
- 接著,它會呼叫
waitForComplete()
來暫停執行,直到要求完成為止。waitForComplete()
API 會封鎖執行 JavaScript 程式碼的執行緒,直到後端完成處理要求並做出回應為止。
訊息處理器隨時能同時執行 JavaScript 程式碼的執行緒數量上限 (30%)。達到上限後,我們將沒有任何可執行 JavaScript 程式碼的執行緒。因此,如果同時在 JavaScript 程式碼中執行 waitForComplete()
API 的並行要求過多,後續要求就會失敗,並顯示「500 內部伺服器錯誤」和「逾時」錯誤訊息,即使 JavaScript 政策逾時也一樣。
一般來說,如果後端需要很長時間才能處理要求,或是流量較大,就可能發生這種情況。
影響程度
- 在 JavaScript 程式碼中執行
waitForComplete()
的並行要求數量超過預先定義的限制時,API 要求就會失敗並顯示 500 Internal Server Error 和 錯誤訊息「逾時」。 - 診斷問題原因可能並不容易,因為 JavaScript 因「逾時」錯誤而失敗 (即使特定 JavaScript 政策的時間限制尚未超過)。
最佳做法
在 HTTP 用戶端中使用回呼可簡化呼叫程式碼、改善效能,並避免在 JavaScript 程式碼中使用 waitForComplete()
。這個方法可確保在 HTTP 要求完成之前,執行 JavaScript 的執行緒不會遭到封鎖。
使用回呼時,執行緒會透過 JavaScript 程式碼傳送 HTTP 要求,並傳回集區。此執行緒已解除封鎖狀態,因此可供處理其他要求。完成 HTTP 要求且回呼也準備就緒後,系統就會建立工作並新增至工作佇列。集區中的其中一個執行緒會根據工作的優先順序執行回呼。
在 httpClient 中使用回呼的 JavaScript 程式碼範例
function onComplete(response,error) { // Check if the HTTP request was successful if (response) { context.setVariable('example.status', response.status); } else { context.setVariable('example.error', 'Woops: ' + error); } } // Specify the callback Function as an argument httpClient.get("http://example.com", onComplete);