WSO2 Enterprise Integrator (EI) facilitates more than one option of routing messages. One of such approaches is to route the request based on its transport headers. This is a variant of the integration pattern content-based routing but rather than checking the message payload, we will be using transport headers to determine the message destination.
For this article, let’s assume a scenario where there are two backend services such that one accepts and responds to JSON messages whereas the other one accepts and responds to XML messages. The integration service will check a ‘Content Type’ of the message and forward the request to the corresponding backend service.
We can use the below switch mediator configuration to achieve the above use case.
<switch source="$trp:Content-Type">
<case regex="application/json">
<send>
<endpoint>
<http uri-template="http://run.mocky.io/v3/dce12279-030d-4190-805c-8a48d5997fec" />
</endpoint>
</send>
</case>
<case regex="application/xml">
<send>
<endpoint>
<http uri-template="http://run.mocky.io/v3/029baaef-a803-486e-a4ad-1ecb1ca0e04a" />
</endpoint>
</send>
</case>
<default>
<payloadFactory media-type="json">
<format>{"Error":"Unsupported Content Type"}</format>
<args />
</payloadFactory>
</default>
</switch>
Alternatively, we can configure the switch mediator below as well.
<switch source="get-property(‘transport’,’Content-Type’">
…
</switch>
But using the synapse xpath variable $trp works better when accessing transport headers [1].
Here is the complete API service with the above switch mediator logic.
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="TestAPI" context="/routing/header">
<resource methods="POST">
<inSequence>
<switch source="$trp:Content-Type">
<case regex="application/json">
<send>
<endpoint>
<http uri-template="http://run.mocky.io/v3/dce12279-030d-4190-805c-8a48d5997fec" />
</endpoint>
</send>
</case>
<case regex="application/xml">
<send>
<endpoint>
<http uri-template="http://run.mocky.io/v3/029baaef-a803-486e-a4ad-1ecb1ca0e04a" />
</endpoint>
</send>
</case>
<default>
<payloadFactory media-type="json">
<format>{"Error":"Unsupported Content Type"}</format>
<args />
</payloadFactory>
</default>
</switch>
<respond />
</inSequence>
</resource>
</api>
After deploying the API service, we can test it using messages with different content types.
JSON:
{“Request”:”JSON Message”}
XML:
<Request>XML Message</Request>
The switch mediator has read the Content-Type header and directed the request to the corresponding backend. If the Content-Type header does not exist or match with any of the cases it will execute the <default> block.
Similarly, you can configure the above API to read a custom header as well.
<switch source="$trp:CustomHeader">
…
</switch>
It allows you to achieve more advanced header-based routing use cases.
We hope the article is clear enough to follow and you will learn something from it. You can find more of such content from our blog section.
Thanks.