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