Go to new doc!

+49 228 5552576-0


info@predic8.com

Tutorial: Exposing SOAP Services as REST Resources

This tutorial will show you how to make a SOAP Web Service accessible as a REST resource.

To run the example do the following:

1. Download Membrane ESB version 3.0.0 or above.

2. Execute router.bat in the MEMBRANE_HOME/examples/soap2Rest directory.
The script router.bat will start the router and load the proxies.xml file.

					<proxies>
						<serviceProxy name="BLZ" port="2000">
							<rest2Soap>
								<mapping regex="/bank/.*" soapAction=""
									soapURI="/axis2/services/BLZService" 
									requestXSLT="get2soap.xsl"
									responseXSLT="strip-env.xsl" />
							</rest2Soap>
							<target host="thomas-bayer.com" />
						</serviceProxy>
					</proxies>
				
Listing 1: proxies.xml

3. Now open the following URL:
http://localhost:2000/bank/37050198
You will receive a response like the following:

					<ns1:getBankResponse 
					  xmlns:ns1=http://thomas-bayer.com/blz/  
					  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
					    <ns1:details>
					      <ns1:bezeichnung>Sparkasse KölnBonn</ns1:bezeichnung>
					      <ns1:bic>COLSDE33XXX</ns1:bic>
					      <ns1:ort>Köln</ns1:ort>
					      <ns1:plz>50667</ns1:plz>
					    </ns1:details>
					</ns1:getBankResponse>
				
Listing 2: Response of BLZService

How it Works

Take a look at the rest2Soap.poxies.xml file. Notice the rest2Soap element. It contains all the information needed to expose a SOAP service as REST resource.

			<rest2Soap>
				<mapping regex="/bank/.*" soapAction=""
					soapURI="/axis2/services/BLZService" 
					requestXSLT="get2soap.xsl"
					responseXSLT="strip-env.xsl" />
			</rest2Soap>
		
Listing 3: Rest2Soap Interceptor

The interceptor can be configured with nested mapping elements.

			<mapping regex="/bank/.*" soapAction=""
				soapURI="/axis2/services/BLZService" 
				requestXSLT="get2soap.xsl"
				responseXSLT="strip-env.xsl" />
		
Listing 4: Rest2Soap Mapping Element

Each mapping element has a regex attribute that will by matched against the URI of incoming requests. The data given by the mapping element which regex matches the URI first will be taken for the following steps. If no match is found nothing will be done.

In this tutorial the regular expression bank/.* will match /bank/37050198 so that the interceptor takes the other data given by the mapping element and continues with the next step.

If we open the following URL in a browser:

http://localhost:2000/bank/37050198

this will send a request like the following one to Membrane.

			GET /bank/37050198 HTTP/1.1
			Host: www.thomas-bayer.com:80
			User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
			Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
			Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
			Accept-Encoding: gzip, deflate
			Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
			Keep-Alive: 115
			Connection: keep-alive
			X-Forwarded-For: 0:0:0:0:0:0:0:1
		
Listing 5: GET Request

Now the rest2Soap interceptor will transform the HTTP request into a temporary XML document. Usually the temporary document can't be seen. Depending on your logging configuration you can see the document dumped into the logfile.

<request method="GET" 
	 http-version="1.1">
  <uri value="/bank/37050198">
    <path>
      <component>bank</component>
      <component>37050198</component>
    </path>
  </uri>
  <headers>
    <header name="Host">localhost:2000</header>
    <header name="User-Agent">Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1</header>
    <header name="Accept">text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</header>
    <header name="Accept-Language">de-de,de;q=0.8,en-us;q=0.5,en;q=0.3</header>
    <header name="Accept-Encoding">gzip, deflate</header>
    <header name="Accept-Charset">ISO-8859-1,utf-8;q=0.7,*;q=0.7</header>
    <header name="Keep-Alive">115</header>
    <header name="Connection">keep-alive</header>
    <header name="X-Forwarded-For">0:0:0:0:0:0:0:1</header>
  </headers>
</request>
		
Listing 6: Temporary XML Document

As you see there are elements for the HTTP headers too. This allows an XSLT stylesheet to reference HTTP headers when constructing the SOAP envelope in the next step. The stylesheet that is used to transform the XML document into a SOAP message is referenced by the mapping attribute "requestXSLT". In our example the stylesheet looks like the following:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	                      xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/">
	<xsl:template match="/">
		<s11:Envelope >
		  <s11:Body>
		    <blz:getBank xmlns:blz="http://thomas-bayer.com/blz/">
		      <blz:blz><xsl:value-of select="//path/component[2]"/></blz:blz>
		    </blz:getBank>
		  </s11:Body>
		</s11:Envelope>	
	</xsl:template>
</xsl:stylesheet>
		
Listing 7: get2soap.xsl

After the transformation the SOAP message will look like the following:

<s11:Envelope xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" 	   
              xmlns:ns1="http://thomas-bayer.com/blz/">
  <s11:Body>
    <ns1:getBank>
      <ns1:blz>37050198</ns1:blz>
    </ns1:getBank>
  </s11:Body>
</s11:Envelope>		
		
Listing 8: Transformed GET
POST /axis2/services/BLZService HTTP/1.1
Host: www.thomas-bayer.com:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
X-Forwarded-For: 0:0:0:0:0:0:0:1
Content-Length: 237
SOAPAction: 
Content-Type: text/xml;charset=UTF-8

<s11:Envelope xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" 	   
              xmlns:ns1="http://thomas-bayer.com/blz/">
  <s11:Body>
    <ns1:getBank>
      <ns1:blz>37050198</ns1:blz>
    </ns1:getBank>
  </s11:Body>
</s11:Envelope>
		
Listing 9: Request Sent to SOAP Service.

Add two log interceptors to the serviceProxy to make the request visible.

					<proxies>
						<serviceProxy name="BLZ" port="2000">
							<log />						
							<rest2Soap>
								<mapping regex="/bank/.*" soapAction=""
									soapURI="/axis2/services/BLZService" 
									requestXSLT="get2soap.xsl"
									responseXSLT="strip-env.xsl" />
							</rest2Soap>
							<log />						
						</serviceProxy>
					</proxies>
				
Listing 10: Added Logs to the serviceProxy

Membrane sends this HTTP message to the target service at www.thomas-bayer.com. The BLZService responses then with the following HTTP message:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 12 May 2011 15:05:17 GMT

195
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <ns1:getBankResponse xmlns:ns1="http://thomas-bayer.com/blz/">
      <ns1:details>
        <ns1:bezeichnung>Sparkasse KölnBonn</ns1:bezeichnung>
        <ns1:bic>COLSDE33XXX</ns1:bic>
        <ns1:ort>Köln</ns1:ort>
        <ns1:plz>50667</ns1:plz>
      </ns1:details>
    </ns1:getBankResponse>
  </soapenv:Body>
</soapenv:Envelope>
0	
Listing 11: SOAP Response

The interceptor than applies another XSLT stylesheet to the body of the response to strip the soap envelope and soap body from the XML document. The stylesheet is referenced by the responseXSLT attribute. You will find a copy of the stylesheet below:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
			      xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/">
							  
	<xsl:template match="/">
		<xsl:apply-templates select="//s11:Body/*"/>
	</xsl:template>
	
	<xsl:template match="@*|node()">
		<xsl:copy>
			<xsl:apply-templates />
		</xsl:copy>
	</xsl:template>	
	
</xsl:stylesheet>
Listing 12: strip-env.xsl

The transformed body will show up in your browser:

					<ns1:getBankResponse 
					  xmlns:ns1=http://thomas-bayer.com/blz/  
					  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
					    <ns1:details>
					      <ns1:bezeichnung>Sparkasse KölnBonn</ns1:bezeichnung>
					      <ns1:bic>COLSDE33XXX</ns1:bic>
					      <ns1:ort>Köln</ns1:ort>
					      <ns1:plz>50667</ns1:plz>
					    </ns1:details>
					</ns1:getBankResponse>
		
Listing 13: Stripped Response