In Edge, is it possible to Run a Policy in a Loop?

Not applicable

Hi,

I want to be able to call an apigee policy in a javasccript loop (for loop to be exact).

Specifically, I have an array of json objects. I want to run the JSON to XML policy on each json object in the array, and get back an array of xml (strings technically, but in xml structure).

I could give the JSON to XML policy the entire array, but then I would have to put that into another script to take the massive string and turn it back into an array. I would prefer to not do that.

Thank you,

Aleks


Addendum

I have this (simplified).

json =

{
 "array": [
   {"a":"1"},
   {"b":"2"},
   {"c":"3"}
  ]
}

I want to convert it to (again simplified).

json =

{
  "array": [
    "<a>1</a>",
    "<b>2</b>",
    "<c>3</c>"
  ]
}

In the real case each json in the array is much longer, and I do not know how many elements the array (value of the key "array") will have. Could be very large.

I could set up an endpoint that calls itself (each time converting one json element to xml), until there are no more objects to convert. Would this be the best method?

Solved Solved
1 9 2,752
1 ACCEPTED SOLUTION

adas
Participant V

@aleks1

You cannot call any Apigee policy from the custom extensions like javascript or javacallout etc. If you are really intent on doing this, here's what I would suggest:

- Have 2 proxies. Proxy 1 has the JSON-to-XML transformation and Proxy 2 is your regular proxy which has all the logic.

- From within a javascript policy in Proxy 2, you can make calls to Proxy 1 using http client with the required payload. This would be like making a service callout to any other API endpoint and you can write your loop construct in the javascript policy which makes calls to the proxy 1 endpoint and aggregates the response.

Note that this would have its own overhead since you are making calls to another proxy endpoint each time. You could further optimise this using "proxy-chaining" which would allow the extra hops to be removed while making calls to another api proxy endpoint hosted in Apigee. Please see details here or refer to our docs about proxy chaining.

View solution in original post

9 REPLIES 9

Former Community Member
Not applicable

Can you show a sample JSON and what you are trying to achieve?

Former Community Member
Not applicable

I would extract the array to a variable. Then use assign message to create a new request object with this variable as source. Finally, use the JSON to XML policy to convert it.

Hi @aleks1,

I have attached a sample proxy bundle that might meet your requirement. You can POST the JSON request payload to this proxy and check if the response is as per your requirement.

jsonarrayv1.zip

I think the example provided here converts a JSON, but doesnot accomplish what the OP asked. It does not call a policy from within a Javascript for loop.

You asked two questions

  1. can I configure Apigee to call a policy in a loop?
  2. Can I convert my JSON to a different JSON

The answer to question #1 is No, it is not possible to run a policy in a loop. In Apigee, there is no looping construct in the Conditional controls within the Proxy flow. Within the JS callout you can create loops, but there is no way to call a policy explicitly from within a Javascript callout.

As regards question #2, what you want to do should be relatively easy to do with a nodejs target that relies on an external library (for example, with this one), or even with a JS callout that uses a library, properly browserified , to help with the JSON-to-XML.

If you need further help with this, let me know. I can produce an example if what I wrote here is not clear.

Addendum

Here's a simplified, naive conversion of JSON to a differently-shaped JSON.

function xform(item) {
  return Object.keys(item).map(function(key) {
    return "<" + key + ">" + item[key] + "</" + key + ">";
  }).join('');
}

var originalJson = {
 array: [
   {"a":"1"},
   {"b":"2"},
   {"c":"3"}
  ]
};

var targetJson = {
  array: [
    "<a>1</a>",
    "<b>2</b>",
    "<c>3</c>"
  ]
};


var actualJson = { array: originalJson.array.map(xform)};

This one uses a simplistic transformation function, but the output is as you described:

{"array":["<a>1</a>","<b>2</b>","<c>3</c>"]}

Hi Dino, I have a similar problem. I want to call one API proxy from another one, using JS Callout. Could you please help with an example.

I haven't been successful in finding examples stating a callout to an api-proxy from java-callout policy.

Yours sounds like a dis-similar problem, unrelated to calling a policy in a loop, which was the topic of the original question.

If you post a new question, we'll try to answer it.

adas
Participant V

@aleks1

You cannot call any Apigee policy from the custom extensions like javascript or javacallout etc. If you are really intent on doing this, here's what I would suggest:

- Have 2 proxies. Proxy 1 has the JSON-to-XML transformation and Proxy 2 is your regular proxy which has all the logic.

- From within a javascript policy in Proxy 2, you can make calls to Proxy 1 using http client with the required payload. This would be like making a service callout to any other API endpoint and you can write your loop construct in the javascript policy which makes calls to the proxy 1 endpoint and aggregates the response.

Note that this would have its own overhead since you are making calls to another proxy endpoint each time. You could further optimise this using "proxy-chaining" which would allow the extra hops to be removed while making calls to another api proxy endpoint hosted in Apigee. Please see details here or refer to our docs about proxy chaining.

@arghya das Thank you, this should accomplish what I desired. @Dino Thank you for the info.