您正在查看 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);