Dohnomis
Dohnomis

Reputation: 25

Transforming JSON array with WSO2 ESB using foreach mediator

I'm using WSO2 ESB V4.9.0 to create a proxy service for a designated end point which needs to return a transformed JSON array. I've setup a proxy service with a foreach mediator and payloadfactory in the out sequence together with log statements to see what is happening. The result is that each of the individual array elements is transformed as expected however the individual elements are not merged back to a single array at the end of the loop as the documentation seems to imply. The result is that only the final element is returned.

Only thing I can see is that most of the examples I've seen don't just have an element with an array rathet than just an array. Anyone know if this is possible?

Original endpoint returns something like this:

[
{"id": "1",
"type": "object",
"name": "first",
"bounds":"[[-0.256,51.531],[-0.102,51.656]]",
"displayName": "first record"},

{"id": "2",
"type": "object",
"name": "second",
"bounds":"[[-0.256,51.531],[-0.102,51.656]]",
"displayName": "second record"},
..etc...
]

Required return from proxy service is like this:

[
{"name": "first record",
"bounds":"[[-0.256,51.531],[-0.102,51.656]]"},
{"name": "second record",
"bounds":"[[-0.256,51.531],[-0.102,51.656]]"},
..etc...
]

Actual return from proxy like this:

{"name": "first record",
"bounds":"[[-0.256,51.531],[-0.102,51.656]]"}

Configuration of the proxy is here:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="newfeed_v2"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log/>
      </inSequence>
      <outSequence>
         <log level="full">
            <property name="MESSAGE" value="FIRST"/>
         </log>
         <foreach id="foreach_1" expression="//jsonArray/jsonElement">
            <sequence>
               <payloadFactory media-type="json">
                  <format>{ 
   "name" : "$1", 
   "bounds" : "$2"  
}</format>
                  <args>
                     <arg evaluator="json" expression="$.displayName"/>
                     <arg evaluator="json" expression="$.bounds"/>
                  </args>
               </payloadFactory>
                <log level="full">
                  <property name="MESSAGE" value="ENDLOOP"/>
               </log>
            </sequence>
         </foreach>
         <log level="full">
            <property name="MESSAGE" value="LAST"/>
         </log>
         <log/>
         <send/>
      </outSequence>
      <endpoint>
         <address uri="https://api.backend.com"/>
      </endpoint>
   </target>
   <description/>
</proxy>

Upvotes: 2

Views: 5162

Answers (2)

VIKRAM
VIKRAM

Reputation: 29

for each mediator will add the splitted expression to the root element so i did like this,

<api context="/foreach" name="foreach" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET">
        <inSequence>
            <payloadFactory media-type="json">
                <format>[
            {"id": "1",
            "type": "object",
            "name": "first",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "first record"},

            {"id": "2",
            "type": "object",
            "name": "second",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "second record"},

            {"id": "4",
            "type": "object",
            "name": "tercero",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "tercer record"}
            ]
                </format>
                <args/>
            </payloadFactory>
            <log level="full">
            </log>
            <foreach expression="//jsonArray/jsonElement">
                <sequence>
                    <payloadFactory media-type="xml">
                        <format>
                            <result xmlns="">
                                <name>$1</name>
                                <bounds>$2</bounds>
                            </result>
                        </format>
                        <args>
                            <arg evaluator="json" expression="$.displayName"/>
                            <arg evaluator="json" expression="$.bounds"/>
                        </args>
                    </payloadFactory>
                </sequence>
            </foreach>
            <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
            <log level="full"/>

            <respond/>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

and i got the response like this

{ "result": [{"name": "first record","bounds": [[-0.256,51.531],[-0.102,51.656]]},{"name": "second record","bounds": [[-0.256,51.531],[-0.102,51.656]]},{"name": "tercer record","bounds": [[-0.256,51.531],[-0.102,51.656]]}]}

Upvotes: 0

Jorge Infante Osorio
Jorge Infante Osorio

Reputation: 2153

Can you try this as a workaround:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="newfeed_v2"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <payloadFactory media-type="json">
            <format>[
            {"id": "1",
            "type": "object",
            "name": "first",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "first record"},

            {"id": "2",
            "type": "object",
            "name": "second",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "second record"},

            {"id": "4",
            "type": "object",
            "name": "tercero",
            "bounds":"[[-0.256,51.531],[-0.102,51.656]]",
            "displayName": "tercer record"}
            ]

            </format>
            <args/>
         </payloadFactory>
         <log level="full"/>
         <loopback/>
      </inSequence>
      <outSequence>
         <log level="full">
            <property name="MESSAGE" value="FIRST"/>
         </log>
         <property name="Person" scope="default">
            <value xmlns=""/>
         </property>
         <foreach id="foreach_1" expression="//jsonArray/jsonElement">
            <sequence>
               <payloadFactory media-type="json">
                  <format>{
                            "name" : "$1",
                            "bounds" : "$2"
                            }
                  </format>
                  <args>
                     <arg evaluator="json" expression="$.displayName"/>
                     <arg evaluator="json" expression="$.bounds"/>
                  </args>
               </payloadFactory>
               <enrich>
                  <source clone="true" xpath="$body//jsonObject"/>
                  <target action="child" xpath="$ctx:Person"/>
               </enrich>
               <log level="full">
                  <property name="MESSAGE1" value="ENDLOOP"/>
               </log>
            </sequence>
         </foreach>
         <enrich>
            <source clone="true" xpath="$ctx:Person"/>
            <target type="body"/>
         </enrich>
         <log level="full">
            <property name="MESSAGE" value="ENDLOOP"/>
         </log>
         <!--property name="messageType" value="text/xml" scope="axis2" type="STRING"/--><log level="full">
            <property name="TRANSFORMED MESSAGE" value="LAST"/>
         </log>
         <send/>
      </outSequence>
      <faultSequence/>
   </target>
   <description/>
</proxy>

My response:

{"value":[{"name":"first record","bounds":"[[-0.256,51.531],[-0.102,51.656]]"},{"name":"second record","bounds":"[[-0.256,51.531],[-0.102,51.656]]"},{"name":"tercer record","bounds":"[[-0.256,51.531],[-0.102,51.656]]"}]}

Upvotes: 5

Related Questions