Discover our knowledge. Read our blogs!

Learn more

We build all our solutions with WSO2 and we are proud that we are WSO2 Premier Certified Integration Partner and Value-Added Reseller.

Learn more

Creating a new Mapped response

15 min read

WSO2 Enterprise IntegratorThere are situations where you get a response from a backend and actually need to change the response. Not so much in the backend, but more in the WSO2 Enterprise Integrator. In this blog we’ll look into how to create a new mapped response.

We created a simple database using Mockaroo, a great service for creating mock data. The great thing is that the data looks more realistic than the often used data sets ‘Jane Doe, John Doe’. For example, I created a database with a table (cars) with the following layout:

Field name Data type
Id INT,
First Name VARCHAR(50),
Last Name VARCHAR(50),
Email VARCHAR(50),
Car VARCHAR(50),
Year VARCHAR(50),

In this database I have 1000 randomly generated records that will allow multiple selections. From the simple select * from cars to select car, count(car) from cars group by car.

First of all, we’ll make this database accessible from the WSO2 Enterprise Integrator (EI) as a datasource. I’m opting for a generated datasource since that is the quickest solution for accessing the data.

This blog builds on several previous blogs and I won’t describe steps like installing WSO2 Products etc.

We have an WSO2 EI up and running and create a datasource that allows a connection to the MySQL / MariaDB database and table. This of course requires the mysql*.jar file to be deployed in the [EI-HOME]/lib directory and a restart of WSO2 Enterprise Integrator. To create the datasource I use the Management UI of the EI since the interface is better than the Developer Studio support. The open source version of WSO2 Enterprise Integrator 6.4.0 unfortunately corrupts a datasource after a restart. This is fixed in WUM updates, but these are available to customers with product support.

Datasources can be configured on the Configure tab. This is the configuration setup. I’m running MariaDB on my local machine. The database is called test and I am using the root / root credentials. However, this is not the idea when you do this in any other setting than a blog like this.

WSO2 Enterprise Integrator - Add new Datasource

I can test the connection and when successful, save the connection. On the Main tab I can now select the Generate option under Datasource. By selecting the datasource and database name, I start generating the services.

WSO2 Enterprise Integrator - Select Datasource

By selecting the table(s) and selecting single service when pressing next, I end up with a Soap based.

WSO2 EI - Customize Service Generation

The generation created two services:

  • - insert_cars_operation;
  • - select_all_car_operation.

The names are self-explanatory. When I try out the second service, I get a response with 1,000 records, the exact number of records in the database.

Furthermore, I am going to add a resource to the dataservice and make it possible to use REST calls with this service.

WSO2 EI - Add resource to dataservice

The dataservice now has this addition in the XML source view.

   <resource method="GET" path="/cars">
     <call-query href="select_all_cars_query"/>
  </resource>

This allows me to do a GET on http://localhost:8280 /services/carsservices/cars in SoapUI.

GET in SoapUI

However, the response is still XML based. But there is a solution for that.

Solution: change the message type

We are creating an API and call the endpoint. In the out sequence we change the messageType to ‘application/json’ so we get a true JSON response.

The setup is simple:

Change message type

Or in the source

<?xml version="1.0" encoding="UTF-8"?>
<api context="/car" name="carAPI" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET">
        <inSequence>
            <send>
                <endpoint>
                    <http method="get" uri-template="http://localhost:8280/services/carsservices/cars"/>
                </endpoint>
            </send>
        </inSequence>
        <outSequence>
            <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

The response is a JSON list of cars.

JSON list of cars

Let’s say that we would like a different kind of message, with only the first name, car and year.

We can of course change the dataservice to select only those fields, but there is also another way (this is often the case with WSO2).

What we’re going to do is to retrieve the message as usual and use one for each mediator with the message, creating a new message layout. We will do that in XML and only change it to JSON when the mediaton is done.

This is because XML is the native message type for the Enterprise Integrator. By setting the messageType to application/json it will be transformed to json before being sent back to the client.

So, how are we going to do that? Well, in the out sequence we will use for each mediator to change the layout of the message. For each mediator it’s a little bit different from the iterate, an aggregate mediator, and is actually meant for message mediation and change.

The source code is still very plain and simple. We don’t necessarily need to do this in the out sequence. A set up where we used the in sequence and a call mediator to call the API and then continuing in the in sequence with the for each mediation would also work. The only thing we need to do of course is to do a response mediator to send the message back to the client.

Graphical overview payload factory

The graphical overview doesn’t say that much about what we’re actually doing in the PayloadFactory Mediator, so let’s take a look at the source code.

<?xml version="1.0" encoding="UTF-8"?>
<api context="/cars2" name="carapi2" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET">
        <inSequence>
            <send>
                <endpoint>
                    <http method="get" uri-template="http://localhost:8280/services/carsservices/cars"/>
                </endpoint>
            </send>
        </inSequence>
        <outSequence>
            <foreach description="" expression="$ctx:body//ns:Entries/ns:Entry" xmlns:ns="http://ws.wso2.org/dataservice"xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <sequence>
                    <payloadFactory media-type="xml">
                        <format>
                            <car>
                                <owner>$1</owner>
                                <make>$2</make>
                                <year>$3</year>
                            </car>
                        </format>
                        <args>
                            <arg evaluator="xml" expression="$ctx:body//ns:first_name"/>
                            <arg evaluator="xml" expression="$ctx:body//ns:car"/>
                            <arg evaluator="xml" expression="$ctx:body//ns:year"/>
                        </args>
                    </payloadFactory>
                </sequence>
            </foreach>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

In the out sequence we use a for each to retrieve every single entry in the response message. The message itself is part of the soap body (we use $ctx:body to reference that) and within the body it will use an XPATH statement (//Entries/Entry) to get every message. Since the for each mediator goes through the entire message in the PayloadFactory Mediator allows us to change the message, we can actually create a new message layout.

If you haven’t worked with the PayloadFactory Mediator, it's a very simple mediation. You define the format you want to message to have, including parameters inside the format. In this case it will create a car tag with three sub- tags: owner, make and year. Each of these values and each of these tags will have the original corresponding value. It’s really as simple as that to change the format. True, this is a simple example, but this is also something that you can elaborate on and make it into something more complex.

As you can see the response is a neat XML message.

Response XML message

The only thing we need to do now is change it to json. The solution is simple: just add a property called messageType and set it to application/json.

 <property name="messageType" scope="axis2" type="STRING" value="application/json"/>

This simple one line changes the output from XML to JSON.

{"Entries": {"car": [
      {
      "owner": "Joceline",
      "make": "Lexus",
      "year": 2010
   },
      {
      "owner": "Lavena",
      "make": "Ford",
      "year": 2002
   },
      {
      "owner": "Rodd",
      "make": "Mazda",
      "year": 1995
   },
Care to share?
   
Picture of Rob Blaauboer
Published October 17, 2019

Rob Blaauboer

Rob is an Integration Consultant & WSO2 Trainer with more than twenty years experience. In addition to his work he is an active blogger working on a number of articles on the ‘Internet of Things’ and a WSO2 ‘Getting Started with …’ series (WSO2 tutorial) in which he talks about WSO2 components and their purpose especially aimed at non technical readers. Rob is a WSO2 expert and official WSO2 trainer.

Responses

Stay up to date with the latest articles