您正在查看 Apigee Edge 說明文件。
前往 Apigee X 說明文件。info
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 Internal Server Error 和「Timed out」在 JavaScript 政策逾時之前顯示錯誤訊息。
一般來說,如果後端處理要求的時間過長,或是流量過高,就有可能會發生這種情況。
影響
- API 要求會失敗,並顯示 500 Internal Server Error 和 錯誤訊息「逾時」在 JavaScript 程式碼中執行
waitForComplete()
的並行要求數量超出預先定義的限制。 - 即使特定 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);