Wednesday, October 3, 2012

REST Support in WSO2ESB - Handling JSON messages

In mobile applications we mostly use JSON messages, since they are easy to process. XML messages need more computational power to build the message.

 To process json messages, we need to enable the required message builder and formatter in the axis2 configuration.

 <messageFormatter  contentType="application/json" class="org.apache.axis2.json. JSONMessageFormatter"/>  

 <messageBuilder contentType="application/json"  class="org.apache.axis2.json. JSONBuilder"/>

Lets look at a sample scenario, where we need to 'GET' a json message from the backend service.
In this sample, we try to retrieve an user details which is stored in a database. To retrieve user details, we may define a simple "select" operation as a data-service.
Say, our data service runs at following endpoint;

http://localhost:9764/services/GetUserDetailsService.

As a second step,we need to define a suitable API for this..
Lets consider the "GET"  will be the only verb we are going to handle.
<api name="getusers" context="/public/user">
      <resource methods="GET"
                url-mapping="/*"
                inSequence="get-users-in-seq"
                faultSequence="fault"/>
   </api>

In the "get-users-in-seq" we might need to call our backend data service to retrieve user details.

 <sequence name="get-users-in-seq">  
      <property xmlns:ns="http://org.apache.synapse/xsd"
                name="userid"
                expression="substring-after(get-property('To'),'/public/user/')"/>
      <payloadFactory>
         <format>
           <p:getUserInfo xmlns:p="http://ws.wso2.org/dataservice">
               <p:Id>$1</p:Id>
            </p:getUserInfo>
        </format>
         <args>
            <arg xmlns:ns="http://org.apache.synapse/xsd"
                 expression="substring-after(get-property('To'),'/public/user/')"/>
         </args>
      </payloadFactory>
      <property name="SOAPAction" value="urn:getUserInfo" scope="transport"/>
      <send receive="recevingGetUserSeq">
         <endpoint>
            <address uri="http://localhost:9764/services/GetUserDetailsService"
                     format="soap11"/>
         </endpoint>
      </send>
   </sequence>
In the above sequence,

We construct the soap message using payloadfactory mediator, in a form which is expected by the backend data-service and send that to backend service. (note that, you can identify the SOAP message format, if you create a soapui project with the dataservice's wsdl.)

Backend service now will return the soap response, which we need to convert back as a json message and need to send back to the client.

   <sequence name="ecevingGetUserSeq">
         <xslt key="gov:/transformations/getUserTransform.xslt">
         <property xmlns:ns="http://org.apache.synapse/xsd"
                   name="userId"
                   expression="get-property('userid')"/>
      </xslt>
      <property name="messageType" value="application/json" scope="axis2"/>
      <send/>
   </sequence>
Here we use a XSLT script, which will formulate the expected json format which client expects.(ie: it will pick relevant info from the soap response and will construct a json message out of it)
Note that, we need to set the  "MessgeType"  property to "application/json", else axis2 wont pick the right message formatter.

We can execute this API with the following curl command to extract the user "Alice's" details.

   curl -v http://localhost:8280/public/user/Alice

Related post;
REST support in WSO2ESB - Introduction