Javascript Policy Callout Request with callback vs WaitForComplete

WaitForComplete() is considered an antipattern, and should be avoided wherever possible.

https://docs.apigee.com/api-platform/antipatterns/wait-for-complete

In its place we now have a callback function that can be used with both the httpClient.get() function and the httpClient.send() function. This is demonstrated in the following community post: https://community.apigee.com/questions/81512/javascript-callback-using-send.html

But there are some nuanced differences between using the callback approach, and using WaitForComplete…

What happens if my callout takes time to respond?

The Javascript policy that it is executing in will not complete until either the call has returned, or the Javascript timeLimit (that you can set in your policy) is reached.

We can test with this a test target endpoint with a delay. For example:

function onComplete(res, err) {
    resp_content = context.getVariable('callout_responses');
    if (res) {
        print("Response received");
        context.setVariable('callout_responses', resp_content + "\n" + res.content);
    } else {
        context.setVariable('callout_responses', resp_content + "\n" + res.err);
    }
}

print("calling with 6 a seconds delay..");
httpClient.get("https://httpbin.org/delay/6", onComplete);
print("calling with a 1 second delay..");
httpClient.get("https://httpbin.org/delay/1", onComplete);

Be sure to increase the ‘timeLimit’ property to be greater than the delay in the endpoint being called. For example:

<Javascript async="false" continueOnError="true" enabled="true" timeLimit="7000" name="JS-callout">

Running the above in a trace session, you will see that the callback printouts for both the 1 second delay callout and the 6 second delay callout appear at the same time. And reducing the timeLimit to below 6 seconds, but above 1 second will likely result in the callback function never getting called, for either request.

Will my proxy flow execution continue while the callback waits to be executed?

No. The next policy will not execute until the callback function has run and the JS policy has finished.

This contrasts greatly with the WaitForComplete function, which can be called on an already running httpClient request object that was executed from an earlier policy.

https://docs.apigee.com/api-platform/reference/javascript-object-model#httpclient.get

However, cases where this is a requirement should be quite rare, and wherever possible, policies should be arranged so that an "onComplete" callback is used instead.

Can I make multiple httpClient calls with callback functions?

Yes, but there is a risk that if any one of the callout requests fail to complete before the Javascript policy’s timeLimit is reached, that none of the callback function executions will happen (even for requests that returned immediately).

This may be the only time when it makes sense to use WaitForComplete: when multiple service callout requests are made simultaneously, and in a type of best-effort approach, you would like to use whatever responses made it back in time. Though, if this is the scenario, it would also be worth considering doing the callouts from the backend/target server, or via a Hosted Target.

Comments
venkatesh_010
Bronze 1
Bronze 1

I've implemented this for multiple calls, question is...in case one of my call is taking time...will the reuqest receive a javascript exeuction timeout? Or it'll get stuck still router or client timeout...currently it's waiting till router timeout and my javascript timeout isn't getting picked up at all and flow isn't moving and this is intermittent and something which I'm not able to catch in apigee trace, as it works when I switch on trace

 

Version history
Last update:
‎08-22-2020 08:16 AM
Updated by: