I create a rest API with 'Get' source.It has parameters in input and with In and Out mediator convert json to soap and then soap to Json to make my output. The output is List of objects. It works correct if there is more than one object in the list. But if I have an object, I expect a list consist of one object in response but the output is just an object. And list is omitted. Is anything wrong with my mediators??
Here is the JsonToSoap mediator(In mediator) :
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesJsonToSoap.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="POST"/>
<header name="Action" scope="default" value="http://tempuri.org/ILivePublisher/LivePrices"/>
<property expression="$url:instrumentIsin" name="req.var.instrumentIsin" scope="default" type="STRING"/>
<property expression="$url:since" name="req.var.since" scope="default" type="STRING"/>
<property expression="$url:to" name="req.var.to" scope="default" type="STRING"/>
<property expression="$url:interval" name="req.var.interval" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<LivePrices xmlns="http://tempuri.org/">
<instrumentIsin>$1</instrumentIsin>
<since>$2</since>
<to>$3</to>
<interval>$4</interval>
</LivePrices>
</s:Body>
</s:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('req.var.instrumentIsin')"/>
<arg evaluator="xml" expression="get-property('req.var.since')"/>
<arg evaluator="xml" expression="get-property('req.var.to')"/>
<arg evaluator="xml" expression="get-property('req.var.interval')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/soap+xml"/>
</sequence>
and the SoapToJson mediator(Out mediator):
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="LivePricesSoupToJson.xml" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<m:Response xmlns:m="http://schemas.xmlsoap.org/soap/envelope/">$1</m:Response>
</format>
<args>
<arg evaluator="xml" expression="//s:Envelope/s:Body/t:LivePricesResponse/t:LivePricesResult/a:Close" xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://tempuri.org/"/>
</args>
</payloadFactory>
<foreach expression="//m:Response/a:Close"
xmlns:a="http://schemas.datacontract.org/2004/07/Asa.Mbdp.Platform.Publish.Tmc.Head.Proxy"
xmlns:m="http://schemas.xmlsoap.org/soap/envelope/">
<sequence>
<payloadFactory media-type="xml">
<format>
<m:LivePrices>
<m:Last>$1</m:Last>
<m:Price>$2</m:Price>
<m:Quantity>$3</m:Quantity>
<m:Since>$4</m:Since>
</m:LivePrices>
</format>
<args>
<arg evaluator="xml" expression="//a:Close/a:Last"/>
<arg evaluator="xml" expression="//a:Close/a:Price"/>
<arg evaluator="xml" expression="//a:Close/a:Quantity"/>
<arg evaluator="xml" expression="//a:Close/a:Since"/>
</args>
</payloadFactory>
</sequence>
</foreach>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
Response with more than one object in list is :
{
"Response": {
"LivePrices": [
{
"Last": 2100,
"Price": 2075,
"Quantity": 29252869,
"Since": "2018-07-18T00:00:00"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:04:35"
},
{
"Last": 2067,
"Price": 2067,
"Quantity": 40790,
"Since": "2018-07-24T11:08:35"
}
]
}
}
and response with one object is :
{
"Response": {
"LivePrices": {
"Last": 1903,
"Price": 1911,
"Quantity": 15345096,
"Since": "2018-07-24T00:00:00"
}
}
}
This is expected behavior of wso2 esb , as what you are doing is blindly converting from XML to json using the property "application/json", so if you have multiple elements only then you get list of objects and if there is only one element then you will get an object as response. You need to use XSLT to do the conversion like below
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="text" indent="yes" media-type="application/json" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">{
"Response":{
"LivePrices":[
<xsl:for-each select="//LivePrices">
{
"Last":"<xsl:value-of select="//Last"/>" ,
"Price":"<xsl:value-of select="//Price"/>"
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
]
}
}
</xsl:template>
</xsl:stylesheet>