Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

JavaScript Policy in Calling the Target Endpoint Multiple Times

Hi Apigee Community,

I have this target endpoint that is a Apigee Proxy also. It accepts billingId as a query parameter. The challenge is, the target endpoint only returns one response per billingId, so they suggested to call the API multiple times and then mapped all the response.  Any suggestion on how to make this using JavaScript policy? I am using Apigee Edge. 

Sample Repeated Requests:
<Proxyendpoint>/customer?billingId=1111

<Proxyendpoint>/customer?billingId=222

<Proxyendpoint>/customer?billingId=333

Then map all the response into one response.


Thanks!

Solved Solved
0 4 869
1 ACCEPTED SOLUTION

Yes, this is a common question here on the Apigee community.  I'd suggest looking through some prior discussions.

In your case, you could use JavaScript with the httpClient and the callback function, to do what you want. 

<Javascript name='JS-Invoke-Calls' timeLimit='4200' >
  <Properties>
    <Property name='target'>https://my-endpoint.com/path</Property>
    <Property name='items'>111,222,333</Property>
    <Property name='qparam'>billingId</Property>
  </Properties>
  <ResourceURL>jsc://invoke-calls-in-parallel.js</ResourceURL>
</Javascript>

And then the JS looks like this: 

var start = Date.now();
var responses = [];

function indexedOnComplete(index, numberOfCalls, response, error) {
  var prefix = 'jscall.'+ index.toFixed(0);
  context.setVariable(prefix +'.completed-at', String(Date.now() - start));
  if (response) {
    context.setVariable(prefix +'.response-status', response.status);
    // collect the response content
    responses.push(JSON.parse(response.content));
  }
  else {
    context.setVariable(prefix +'.error', 'Whoops: ' + error);
    responses.push(null);
  }

  // check if this is the final response. If so, set result variables in context.
  if (numberOfCalls == responses.length) {
    context.setVariable('jscall.all-done', String(Date.now() - start));
    // all of the responses
    context.setVariable('jscall.aggregated-result',
                        JSON.stringify(responses, null, 2));
  }
}

// invoke one outbound http call, using the callback method
function invokeOne(item, index, cb) {
  var url = properties.target + '?' + properties.qparam + '=' + item ;
  var headers = { 'Item-Index' : index };
  httpClient.send(new Request(url, 'GET', headers), cb);
}

// ====================================================================
var items = properties.items.split(new RegExp('\\s*,\\s*'));
var numberOfCalls = items.length;
context.setVariable('number-of-calls', numberOfCalls.toFixed(0));

items.forEach(function(currentItem, index) {
  context.setVariable('jscall.' + index.toFixed(0) + '.item', currentItem);
  var cb = function(response, error) {
        return indexedOnComplete(index, numberOfCalls, response, error);
      };
  return invokeOne(currentItem, index, cb);
});

View solution in original post

4 REPLIES 4