How to remove few fields from JSON array response?

abhinabanag92
Participant III

I am getting a JSON response like below:

[
  {
    "id": "1",
    "name": "Abhi",
    "pan": "ABC",
    "bg": "O+"
  },
  {
    "id": "2",
    "name": "Ashish",
    "pan": "XYZ",
    "bg": "AB+"
  },
  .
  .
  .
]
and I want to remove the "pan" and "bg" field from all elements of the array in the final response.Like below:
[
  {
    "id": "1",
    "name": "Abhi"
  },
  {
    "id": "2",
    "name": "Ashish"
  },
  .
  .
  .
]
Solved Solved
1 10 20K
1 ACCEPTED SOLUTION

abhinabanag92
Participant III

I have resolved this issue placing a Javascript Policy between Extract variable policy and Assign Message policy.

Inside Javascript policy, I'm taking the whole payload in a variable, converting it to an array, mapping required fields to another array, and then converting the second array to JSON object.

Extract Variable Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-FullData">
    <DisplayName>EV-FullData</DisplayName>
    <Properties/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <JSONPayload>
        <Variable name="resp">
            <JSONPath>$</JSONPath>
        </Variable>
    </JSONPayload>
    <Source clearPayload="false">response</Source>
    <VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

Javascript Policy code:

var res = context.getVariable("apigee.resp");
var result = [];
var result = JSON.parse(res);
var newArr = result.map(item => { return {
  id: item.id,
  name: item.name
}});
var output = JSON.stringify(newArr);
context.setVariable("apigee.resp",output);

Assign Message Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-FinalResponse">
    <DisplayName>AM-FinalResponse</DisplayName>
    <Properties/>
    <Set>
        <Payload>
            {apigee.resp}
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

View solution in original post

10 REPLIES 10

abhinabanag92
Participant III

Currently, I'm using Extract variable policy and Assign Message policy,

Extract Variable Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-FullData">
    <DisplayName>EV-FullData</DisplayName>
    <Properties/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <JSONPayload>
        <Variable name="id">
            <JSONPath>$[*].id</JSONPath>
        </Variable>
    </JSONPayload>
    <Source clearPayload="false">response</Source>
    <VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

Assign Message Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-FinalResponse">
    <DisplayName>AM-FinalResponse</DisplayName>
    <Properties/>
    <Set>
        <Payload>[{
            "id":"{apigee.id}"
        }]
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>
and I'm getting response like below:
[
    {
        "id": "["1","2"]"
    }
]

Are these the results that you want? I'm not clear. Are you still experiencing a problem?

The response I'm getting:

[
    {
        "id": "["1","2"]"
    }
]

The response I want:

[
  {
    "id": "1",
    "name": "Abhi"
  },
  {
    "id": "2",
    "name": "Ashish"
  },
  .
  .
  .
]

Ahh, I see. Sorry I had missed that.

What you are trying would work with a current jsonpath processor, if you used this as your jsonpath:

$[*].['id','name']

Unfortunately, the ExtractVariables depends on an older jsonpath library, which does not accept that syntax. So you cannot use ExtractVariables to do that, today.

In fact I don't know of a way to do that, with the currently built-in policies in Apigee. You can do it if you use a more current jsonpath library, like jayway jsonpath 2.4.0. This Java callout does it:

https://github.com/DinoChiesa/ApigeeEdge-Java-JSONPath

Configuration would be:

<JavaCallout name="Java-JSON-Path-Multiple-Fields">
  <Properties>
    <Property name='jsonpath'>$[*]['id','name']</Property>
    <Property name='source'>message.content</Property>
  </Properties>
  <ClassName>com.google.apigee.edgecallouts.jsonpath.JsonPathCallout</ClassName>
  <ResourceURL>java://edge-callout-jsonpath-20191216.jar</ResourceURL>
</JavaCallout>

abhinabanag92
Participant III

I have resolved this issue placing a Javascript Policy between Extract variable policy and Assign Message policy.

Inside Javascript policy, I'm taking the whole payload in a variable, converting it to an array, mapping required fields to another array, and then converting the second array to JSON object.

Extract Variable Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-FullData">
    <DisplayName>EV-FullData</DisplayName>
    <Properties/>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <JSONPayload>
        <Variable name="resp">
            <JSONPath>$</JSONPath>
        </Variable>
    </JSONPayload>
    <Source clearPayload="false">response</Source>
    <VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

Javascript Policy code:

var res = context.getVariable("apigee.resp");
var result = [];
var result = JSON.parse(res);
var newArr = result.map(item => { return {
  id: item.id,
  name: item.name
}});
var output = JSON.stringify(newArr);
context.setVariable("apigee.resp",output);

Assign Message Policy code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-FinalResponse">
    <DisplayName>AM-FinalResponse</DisplayName>
    <Properties/>
    <Set>
        <Payload>
            {apigee.resp}
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

getting error in javascript policy at JSON parse line number 3 as invalid token

You need to check the response is in proper format to become json parsed. Just do a response validation.

getting error like this .Cannot find function map in object [object Object]

Then you have to fix and make the response parsed as a json object

mikeSixx
Participant I

Using ExtractVariables policy and JSONPath will do just that. 

<ExtractVariables continueOnError="false" enabled="true" name="EV-xxx">
  <JSONPayload>
    <Variable name="nopanbg">
      <JSONPath>$[*].['id','name']</JSONPath>
    </Variable>
  </JSONPayload>
</ExtractVariables>

Then ofc you need to outout the variable with AssignMessage policy :

<AssignMessage continueOnError="false" enabled="true" name="AM-NoPanBgResponeBody">
  <Set>
    <Payload contentType="application/json">{nopanbg}</Payload>
  </Set>
  <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>