您正在查看 Apigee 和 Apigee Hybrid 文档。
查看 Apigee Edge 文档。
JavaScript 政策允许您添加在 API 代理流上下文中执行的自定义代码。例如,JavaScript 政策中的自定义代码可用于:
- 获取和设置流变量
- 执行自定义逻辑并执行故障处理
- 从请求或响应中提取数据
- 动态修改后端目标网址
- 在请求或响应中动态添加或移除标头
- 解析 JSON 响应
HTTP 客户端
HTTP 客户端是 JavaScript 政策的一项强大功能。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 代码向后端 API 发送 HTTP 请求。
- 然后,它调用
waitForComplete()来暂停执行,直到请求完成。waitForComplete()API 阻止执行 JavaScript 代码的线程,直到后端完成请求处理并发回响应。
任何时候在消息处理器中并行执行 JavaScript 代码的线程数上限为 30%。达到该限制后,将会没有任何线程可以执行 JavaScript 代码。因此,如果 JavaScript 代码中执行 waitForComplete() API 的并发请求过多,则后续请求将失败,并返回 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);