Transforming the response of an API on the fly
An API hosted in the WSO2 API Cloud receives requests sent from your consumer applications to your backend, and then sends the responses from the backend to you. The default flow of events of an API hosted in the WSO2 API Cloud is shown in the diagram below.
If you need to modify or transform the requests and responses of your API, you need to engage a message mediation that intercepts the default flow.
Let’s take a look at a real world example of how message mediation happens in the API Cloud gateway.
In order to understand how to extend the message flow of APIs in the real world let’s take an example from the moderately complex section above and look at it in detail. In this example I will elaborate how message mediation is useful when you need to manipulate the message body being sent or received from the backend service.
Example Use Case
Background
Your backend service returns details of a country based on a country code which you pass. The backend response is a highly elaborate response about all the country’s details.
Your backend is only capable of returning the response in XML format.
Our Requirement.
The end user needs the response to only contain the country name being referenced by the country code and its region, omitting all other details returned in the response.
The end user wants the response format to be the content type which he/she request. I:e If he/she request for json then the API should return the response in JSON, If they request it to be xml then it should return it in XML, irrespective of the format the backend service returns.
The extension to the default message flow is represented in the diagram below.
This can be easily achieved without you having to change either the front end application logic or the backend service logic using custom mediation policies in the WSO2 API Cloud. Below is the custom policy which we need to engage to our API.
I have briefly explained the changes done to your message within the custom policy to change the output returned from the backend to meet our requirements. Such a file which has this kind of message mediation logic is referred to as a custom sequence.
We need to intercept the default message flow at two points. During the request message flow we need to capture the response type the user needs to have the final response in and preserve it. See the policy file to achieve this below.( Download policy here)
<sequence xmlns=”http://ws.apache.org/ns/synapse" name=”message_mediation_sample_policy_in”>
<! — This property extracts and stores the Accept header in the request which is sent by the consumer →
<property name=”requestedAcceptHeader” expression=”$trp:Accept”/>
</sequence>
Then when the message is sent back to the consumer we need to transform the message and set the requested response format. See the policy file to achieve this below. (Download policy here)
<sequence xmlns=”http://ws.apache.org/ns/synapse" name=”message_mediation_sample_policy_out”>
<payloadFactory media-type=”json”>
<! — Here you specify the format of the message you need to output →
<format>
{ “countries”:{“Country Name”: “$1”,“Region”: “$2”}}
</format>
<! — Used to extract the elements from the XML payload and then assigns them to the variables $1 and $2 respectively. First argument is assigned to the variable $1 and the second to $2 →
<args>
<arg expression=”$body//wb:countries/wb:country/wb:name/text()” xmlns:wb=”http://www.worldbank.org" evaluator=”xml”/>
<arg expression=”$body//wb:countries/wb:country/wb:region/text()” xmlns:wb=”http://www.worldbank.org" evaluator=”xml”/>
</args>
</payloadFactory>
<! — Extracts the header which we preserved in the in flow as “requestedAcceptHeader” pertaining to the messsage type the consumer required the response to be →
<! — This property will then convert the response into that type eg: JSON or XML →
<property name=”messageType” expression=”get-property(‘requestedAcceptHeader’)” scope=”axis2"/>
</sequence>
Let’s try this out!!
We will add the custom policy later. Let’s first design our API to try out this example.
- Register to the WSO2 API Cloud and go to the API publisher. [1] API Publisher is the API developer portal which allows you to design your API, map to your backend services and let’s you manage your API.
- On the top menu of the API Publisher you will see an option as “API Cloud Walkthrough”. Click on that option and complete the step by step guide to create the API we are going to use for this example..
3. Here we are defining a GET resource as countries/{code} where a code parameter needs to be input by the end user.
And mapping the backend service of this API to http://api.worldbank.org. (All this is explained in the walkthrough)
4. Once you have completed the walkthrough tutorial you will see the response which you get from your API does not meet our requirement mentioned in our use case above. Let’s change it.
5. You need to add mediation policies to your API which has the custom logic for the transformation we need. You can download the policy file for the in flow(request flow) from here and the one for the out flow(response flow) from here.
6. Next upload it to the in flow and the out flow respectively of the API as shown below. Steps on how to add this to your API can be found here. Follow this guide to add these policies to your API
7. Now save and publish your API once more. Go back to the Store and invoke your API giving the country code as “au” and Accept header as application/json. You will see a changed response as shown below.
8. Now invoke the API giving the Accept header as application/xml. You will see the response will be returned in XML format.
That’s it! You have successfully extended the default message flow of your API.
If you want to try out more similar message transformation use cases you can refer our message mediation cookbook which is a guide consisting of many more examples. If your use case is not listed here you can contact us as cloud@wso2.com and we can assist you build up custom mediation for your APIs today!