Search code examples
jsonrestpostesbmule

How to POST to REST api from Mule Flow?


I need some help with Mule 3 esb. I am reading a message from a JMS Queue and then I want to POST some parts of this message to an external REST api and handle the response. I have only used Mule to talk to databases before and never for web services. Can you help me figure out what I need to do to correctly POST to this api and handle the response. Should I use a java component instead of doing it in the flow?

Here is a sample XML message from the JMS queue

<longUrl>http://www.cnn.com</longUrl>

Here is my flow

<flow name="myFlow" doc:name="myFlow">

    <jms:inbound-endpoint queue="input" connector-ref="jmsConnector" doc:name="JMS">
        <jms:transaction action="ALWAYS_BEGIN"/>
    </jms:inbound-endpoint>        

    <logger message="#[payload]" level="INFO" doc:name="Logger"/>

    <choice doc:name="Choice">
        <when expression="payload.size() &gt; 0" evaluator="groovy">
            <processor-chain>
                <logger message="****** Create short url *******" level="INFO" doc:name="Logger"/>                                        
                <https:outbound-endpoint method="POST" exchange-pattern="request-response" address="https://www.googleapis.com/urlshortener/v1/url" contentType="application/json" doc:name="HTTP"/>
            </processor-chain>
        </when>
        <otherwise>
            <processor-chain>
                <message-properties-transformer doc:name="Message Properties">
                    <add-message-property key="Content-Type" value="text/plain"/>
                </message-properties-transformer>
                <expression-transformer doc:name="Expression">
                    <return-argument evaluator="string" expression="no parameter is given!"/>
                </expression-transformer>
            </processor-chain>
        </otherwise>
    </choice>      

</flow>

Solution

  • You need to transform the XML into JSON before POSTing to the Google API.

    I did this in two steps:

    • extract the long URL with XPath and create a map out of it,
    • transform the map to JSON.

    Here is the relevant configuration bit:

    <processor-chain>
        <logger message="****** Create short url *******"
            level="INFO" doc:name="Logger" />
        <expression-transformer expression="['longUrl':xpath('/longUrl').stringValue]" />
        <json:object-to-json-transformer />
        <https:outbound-endpoint
            method="POST" exchange-pattern="request-response"
            address="https://www.googleapis.com/urlshortener/v1/url"
            contentType="application/json" doc:name="HTTP" />
    </processor-chain>
    

    With this in place, I get a correct JSON response:

    {
     "kind": "urlshortener#url",
     "id": "http://goo.gl/2ViC",
     "longUrl": "http://www.cnn.com/"
    }