The REST web services are becoming more and more popular, because of their simplicity over the SOAP and WSDL-based web services. This recipe will explore how to call the RESTful web services from the BPEL process.
We have prepared a RESTful web service that returns the weather conditions based on the city criteria. The web service is developed in JDeveloper and deployed to the Oracle SOA Suite server. We developed the RESTful web services with Jersey, which supports the JAX-RS (the Java API for the RESTful web services) specification covered by Java Specification Request 311.
We created the sample RESTful weather service with the following code:
@Path("RESTWeatherService") public class WeatherProvider { @GET @Path("/query") @Produces("text/xml") public String getWeatherInfo(@QueryParam("name") String name,@QueryParam("zip") String zip) { return "<weatherRes>Hello " + name + ". The weather in " + zip + " city cloudy. " + "Temperature is 24 degrees Celsius. " + "Humidity is 74%</weatherRes>"; } }
The highlighted text marks the JAX-RS annotations. With the @Path
annotation, we identify the path where the RESTful services will reside. With the @GET
annotation, we identify the type of the communication we will use with the service. The @Path
annotation on the method identifies the subpath of the service. The @Produces
annotation defines the type of the response we will receive as a result of the service call, in our case, text/xml. The @QueryParam
annotation identifies the parameter of the web service. The source file is then packed into the WAR file and deployed into Oracle SOA Server.
There exists many ways to call the RESTful web services from the BPEL process.
We will learn how to call the RESTful web service from the BPEL process by modifying the WSDL document. Instead of defining the web service in the <wsdl:binding>
element of WSDL, we will use the
<http:binding>
element.
As an input and output messages, we define the following structure: <types> <xsd:schema elementFormDefault = "qualified" targetNamespace = "http://org.packt.rest/Weather"> <xsd:element name = "weatherRes" type = "xsd:string"/> <xsd:element name = "weatherReq"> <xsd:complexType> <xsd:sequence> <xsd:element name = "name" type = "xsd:string"/> <xsd:element name = "zip" type = "xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </types> <message name = "GetWeather"> <part name = "payload" element = "tns:weatherReq"/> </message> <message name="GetWeatherResponse"> <part name = "payload" element = "tns:weatherRes"/> </message>
<portType name = "WeatherPT"> <operation name = "QueryWeather"> <input message = "tns:GetWeather"/> <output message = "tns:GetWeatherResponse"/> </operation> </portType>
<wsdl: binding>
element we use the <http:binding>
element. Also the input and output message elements have the HTTP namespaces as follows:<binding name = "WeatherBind" type = "tns:WeatherPT"> <http:binding verb = "GET"/> <operation name = "QueryWeather"> <http:operation location = "/weather"/> <input> <http:urlEncoded/> </input> <output> <mime:mimeXml part="payload"/> </output> </operation> </binding>
<service name = "WeatherService"> <port name = "Weather" binding = "tns:WeatherBind"> <http:address location = "http://medion:7001/weatherservice/jersey/RESTWeatherService/query"/> </port> </service>
<assign name = "AssignParams"> <copy> <from>$inputVariable.payload/client:MyName</from> <to>$CallWeather_QueryWeather_InputVariable.payload/ns2:name</to> </copy> <copy> <from>$inputVariable.payload/client:MyZip</from> <to>$CallWeather_QueryWeather_InputVariable.payload/ns2:zip</to> </copy> </assign>
<invoke name = "CallWeather" partnerLink = "WeatherSvcs" portType = "ns2:WeatherPT" operation = "QueryWeather" inputVariable = "CallWeather_QueryWeather_InputVariable" bpelx:invokeAsDetail = "no" outputVariable = "CallWeather_QueryWeather_OutputVariable"/>
<assign name = "AssignResult"> <copy> <from>$CallWeather_QueryWeather_OutputVariable.payload</from> <to>$outputVariable.payload/client:result</to> </copy> </assign>
The Oracle BPEL server does not support a call to the RESTful web services out-of-the-box. Instead, we need to use a trick. By providing the WSDL description of the RESTful web services, we enable a call from the BPEL process to the RESTful web services. The crucial change in the WSDL document is done inside the <wsdl:binding>
tag.
In this recipe, we provide one way of calling the RESTful web services from the BPEL process. Oracle SOA Suite also provides the mediator functionality, which can be utilised to invoke the RESTful web services.
The WSDL document supports the following two types of bindings:
<soap:binding>
: This attribute is described with the style and transport types. Its most common usage is the document for style and HTTP as a transport.<http:binding>
: This is what we used to call the RESTful web services. We define it to use the GET
method over HTTP to communicate with the web service.With the operation attribute, we define the operations that portType
exposes. Inside the operation attribute, we usually define the SOAPAction
parameter as follows:
<soap:operation soapAction = "<URI>"/>
Instead of <soap:operation>
, we use <http:operation>
. We define on which path the web service is found as follows:
<http:operation location = "/weather"/>
The binding element in the WSDL document of the weather service now reads as follows:
<binding name = "WeatherBind" type = "tns:WeatherPT"> <http:binding verb = "GET"/> <operation name = "QueryWeather"> <http:operation location = "/weather"/> <input> <http:urlEncoded/> </input> <output> <mime:mimeXml part="payload"/> </output> </operation> </binding>