您正在查看 Apigee 和 Apigee Hybrid 說明文件。
查看
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', response.status);
} else {
error = exchangeObj.getError();
context.setVariable('example.error', 'Woops: ' + error);
}
在這個範例中:
- JavaScript 程式碼會將 HTTP 要求傳送至後端 API。
- 接著,它會呼叫
waitForComplete()暫停執行,直到要求完成為止。waitForComplete()API 會導致執行 JavaScript 程式碼的執行緒遭到封鎖,直到後端完成處理要求並回應為止。
在任何時間點,可同時在訊息處理器上執行 JavaScript 程式碼的執行緒數量 (30%) 有上限。達到此限制後,就不會有任何執行緒可執行 JavaScript 程式碼。因此,如果 JavaScript 程式碼中執行 waitForComplete() API 的並發要求過多,後續要求就會失敗,並在 JavaScript 政策逾時前顯示 500 Internal Server Error 和 Timed out 錯誤訊息。
一般來說,如果後端處理要求的時間過長,或是流量過高,就可能發生這種情況。
影響
- 如果 JavaScript 程式碼中執行
waitForComplete()的並行要求數量超過預先定義的限制,API 要求就會失敗,並顯示500 Internal Server Error和錯誤訊息Timed out。 - 即使特定 JavaScript 政策的時間限制尚未到期,JavaScript 仍會因
Timed out錯誤而失敗,因此診斷問題原因可能會相當棘手。
最佳做法
請在 HTTP 用戶端中使用回呼,簡化說明代碼並提升效能,並避免在 JavaScript 程式碼中使用 waitForComplete()。這個方法可確保執行 JavaScript 的執行緒不會在 HTTP 要求完成前遭到封鎖。
使用回呼時,執行緒會在 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);