This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

In addition to exposing RESTful interfaces and mediating RESTful invocations by mapping REST concepts to SOAP via proxy services, you can use the WSO2 ESB REST API to configure REST endpoints in the ESB by directly specifying HTTP verbs, URL patterns, and URI templates. This page describes how you can use the REST API to handle the following use cases:

For information on securing APIs, see Securing REST APIs with Basic Auth.

Exposing a SOAP Service Over REST

In this scenario, you expose a SOAP service over REST using an ESB REST API.  


 
 

For the SOAP back-end service, we are using the StockQuote Service that is shipped with ESB. Configure and start the back-end service as described in Starting Sample Back-End Services. We will use cURL as the REST client to invoke the ESB REST API.

Following is a sample API configuration that we can used to implement this scenario.

<api name="StockQuoteAPI" context="/stockquote">
   <resource uri-template="/view/{symbol}" methods="GET">
      <inSequence>
         <payloadFactory>
        <format>
        <m0:getQuote xmlns:m0="http://services.samples">
                <m0:request>
                   <m0:symbol>$1</m0:symbol>
                </m0:request>
             </m0:getQuote>
        </format>
        <args>
        <arg expression="get-property('uri.var.symbol')"/>
        </args>
     </payloadFactory>
     <send>
        <endpoint>
        <address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
        </endpoint>
     </send>
      </inSequence>
      <outSequence>
     <send/>
      </outSequence>
   </resource>
   <resource url-pattern="/order/*" methods="POST">
      <inSequence>
        <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
    <property name="OUT_ONLY" value="true"/>
    <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService" format="soap11"/>
            </endpoint>
         </send>
      </inSequence>      
   </resource>
</api>
</definitions>

In this API configuration we have defined two resources. One is for the HTTP method GET and the other one is for POST. 

In the first resource, we have defined the uri-template as /view/{symbol} so that request will be dispatched to this resource when you invoke the API using the following URI:

http://127.0.0.1:8280/stockquote/view/IBM 

Following is the cURL command to send this URI:

curl -v http://127.0.0.1:8280/stockquote/view/IBM

The context of this API is stockquote.

The SOAP payload required for the SOAP back-end service is constructed using the payload factory mediator defined in the inSequence. The value for the <m0:symbol> element is extracted using the following expression:

get-property('uri.var.symbol')

Here ‘symbol’ refers to the variable we defined in the uri-template (/view/{symbol}). Therefore, for the above invocation, the 'uri.var.symbol' property will resolve to the value ‘IBM’.

After constructing the SOAP payload, the request will be sent to the SOAP back-end service from the <send> mediator, which has an address endpoint defined inline with the format="soap11" attribute in the address element. The response received from the back-end soap service will be sent to the client in plain old XML (POX) format. 

In the second resource, we have defined a URL pattern as "/order/*". Since this has POST as the HTTP method, the client has to send a payload to invoke this. Following is a sample cURL command to invoke this:

curl -v -d @placeorder.xml -H "Content-type: application/xml" http://127.0.0.1:8280/stockquote/order/

Save the following sample place order request as placeorder.xml in your local file system and execute the command. This payload is used to invoke a SOAP service.  

<placeOrder xmlns="http://services.samples">
  <order>
     <price>50</price>
     <quantity>10</quantity>
     <symbol>IBM</symbol>
  </order>
</placeOrder>

You will see something similar to following line printed in the sample axis2 server (back-end server) console.

Tue Mar 19 09:30:33 IST 2013 samples.services.SimpleStockQuoteService  :: Accepted order #1 for : 10 stocks of IBM at $ 50.0

This SOAP service invocation is an OUT_ONLY invocation, so the ESB is not expecting any response back from the SOAP service. Since we have set the FORCE_SC_ACCEPTED property value to true, the ESB returns a 202 response back to the client.

Exposing a Back-End REST Service Using an ESB REST API

In this scenario, we are exposing a back-end REST service using an ESB REST API. That means we are exposing a different REST API to the client for a REST back-end service.  


 
 

For the REST back-end service, we are going to use the JAX-RS Basics sample service available in the WSO2 Application Server 5.0.1. Configure and deploy the JAX-RS Basics sample by following the instructions for building and running the sample on the JAX-RS Basics page. Since we are going to run both WSO2 ESB and the WSO2 Application Server on the same machine, we have to offset the ports of Application Server by changing the offset value to 1 in <AS_HOME>/repository/conf/carbon.xml. 

Following is a sample configuration we can use to configure this scenario:

<api xmlns="http://ws.apache.org/ns/synapse" name="ClientServiceAPI" context="/clientservice">
   <resource methods="OPTIONS DELETE GET" uri-template="/clients/{id}">
      <inSequence>

         <property name="REST_URL_POSTFIX" 
expression="fn:concat('/customers/',get-property('uri.var.id'))" 
scope="axis2"/>
         <send>
            <endpoint>
               <address uri="http://localhost:9764/jaxrs_basic/services/customers/customerservice/"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </resource>
   <resource methods="POST PUT" uri-template="/clients">
      <inSequence>
         <property name="REST_URL_POSTFIX" value="/customers" scope="axis2"/>
         <switch source="$ctx:REST_METHOD">
            <case regex="POST">
               <payloadFactory>
                  <format>
                     <Customer xmlns="">
                        <name>$1</name>
                     </Customer>
                  </format>
                  <args>
                     <arg expression="//addClient/name"/>
                  </args>
               </payloadFactory>
            </case>
            <case regex="PUT">
               <payloadFactory>
                  <format>
                     <Customer xmlns="">
                        <id>$1</id>
                        <name>$2</name>
                     </Customer>
                  </format>
                  <args>
                     <arg expression="//updateClient/id"/>
                     <arg expression="//updateClient/name"/>
                  </args>
               </payloadFactory>
            </case>
         </switch>
         <send>
            <endpoint>
               <address uri="http://localhost:9764/jaxrs_basic/services/customers/customerservice/"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </resource>
</api>

The service URL for the back-end REST service is:

http://localhost:9764/jaxrs_basic/services/customers/customerservice/

The service URL for the REST API (ClientServiceAPI) is:

http://localhost:8280/clientservice/                        

As you can see, we have exposed the back-end REST service in a different context using this REST API. In addition to altering the context, the API is accepting the payload in a different format.

For the HTTP POST method, the back-end REST service accepts the payload in the following format:

<Customer>
   <name>Jack</name>
</Customer>

The ClientServiceAPI accepts the payload in the following format:

<addClient>
   <name>Jack</name>
</addClient>

For the HTTP PUT method, the back-end REST service accepts the payload in the following format:

<Customer>
   <id>123</id>
   <name>John</name>
</Customer>

The ClientServiceAPI accepts the payload in the following format:

<updateClient>
   <id>123</id>
   <name>John</name>
</updateClient>

Conversion of the payload format is done using the <payloadFactory> mediator.

We have now exposed a different REST API for the REST back-end services using an ESB REST API. In the ClientServiceAPI, there are two resources. The first resource is for the GET, OPTIONS, and DELETE HTTP methods. URL postfix is needed for the REST back-end service and is calculated using the following expression:

fn:concat('/customers/',get-property('uri.var.id'))

The calculated URL postfix is appended to the back-end service URL, as we have set that value to the REST_URL_POSTFIX property. Therefore, the final request URL will be something similar to the following:

http://localhost:9764/jaxrs_basic/services/customers/customerservice/customers/123

Following is the cURL command to send a GET request to the API:

curl -v http://localhost:8280/clientservice/clients/123 

You will see the following line printed as the response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Customer><id>123</id><name>John</name></Customer>

The second resource is for the POST and PUT HTTP methods. The incoming REST request is filtered using the HTTP_METHOD, and the appropriate payload required for the back-end REST service is constructed using the <payloadFactory> mediator.

Following is the cURL command to send a POST request to the API:

curl -v -d @addClient.xml -H "Content-type: application/xml" http://localhost:8280/clientservice/clients 

Content of the addClient.xml file should be in the following format:

<addClient>
   <name>WSO2</name>
</addClient>

When you execute the above command in the application server console, the following line will be printed:

----invoking addCustomer, Customer name is: WSO2

Following is the cURL command to send a PUT request to the API:

curl -v -d @updateClient.xml -X PUT -H "Content-type: application/xml" http://localhost:8280/clientservice/clients

The content of the updateClient.xml file should be in the following format:

<updateClient>
    <id>123</id>
    <name>ESB</name>        
</updateClient>

When you execute the above command in the application server console, the following line will be printed:

----invoking updateCustomer, Customer name is: ESB

Enabling REST to JMS

This section describes how a REST API can receive an HTTP message sent from a REST client and place it on a JMS queue.


  
 

The API receives the HTTP message and sends it to a JMS queue that resides in a message broker. The back-end service listens and picks up the message from this queue. For the back-end service, we are using the StockQuote Service that is shipped with ESB. Configure and start the back-end service as described in Starting Sample Back-End Services. We will use cURL as the REST client to invoke the ESB REST API.

For this sample, we use ActiveMQ 5.5.1 as the message broker. Start ActiveMQ and configure the JMS transport in ESB to work with ActiveMQ before you proceed.

Following is a sample ESB API configuration that we can used to implement this scenario:

<api xmlns="http://ws.apache.org/ns/synapse" name="RestToJmsAPI" context="/stockquote">
   <resource methods="POST" url-mapping="/order/*">
      <inSequence>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
         <property name="OUT_ONLY" value="true"/>
         <send>
            <endpoint>
               <address uri="jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616" format="soap11"/>
            </endpoint>
         </send>
      </inSequence>
   </resource>
</api>

In this API configuration, we have set the OUT_ONLY property to true, as it is a one-way invocation. The message is sent to the JMS queue using the JMS Transport sender. (Note the prefix “jms” in the address endpoint URI.) Since we have set the FORCE_SC_ACCEPTED property value to true, the ESB returns a 202 response back to the client. 

Following is a sample cURL command to invoke this API:

curl -v -d @placeorder.xml -H "Content-type: application/xml" http://127.0.0.1:8280/stockquote/order/

Save the following sample place order request as "placeorder.xml" in your local file system and execute the above command.

<placeOrder xmlns="http://services.samples">
  <order>
     <price>50</price>
     <quantity>10</quantity>
     <symbol>IBM</symbol>
  </order>
</placeOrder>

You will see the something similar to the following printed in the sample axis2 server (back-end server) console:

Tue Mar 19 09:30:33 IST 2013 samples.services.SimpleStockQuoteService  :: Accepted order #1 for : 10 stocks of IBM at $ 50.0

Shut down the back-end server and execute the command again. If you go to the ActiveMQ Console and inspect the SimpleStockQuoteService queue, you will see a message queued there.

 

  • No labels