2.21. Web Services

Web services standardize an infrastructure for integrating information systems in the environment of the Internet. The two major web services standards are the Simple Object Access Protocol (SOAP) and the Web Service Description Language (WSDL).

2.21.1. SOAP

The SOAP standard by W3C defines a communication protocol based on a textual form of message encoding in XML. Each message consists of a series of optional headers and a body, with the headers carrying information intended for systems that route the message and the body intended for the final recipient of the message. The messages are extensible and easy to transport via HTTP.

Message Example

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"
               SOAP:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <!-- Header with additional information -->
    <SOAP:Header>
        <wscoor:CoordinationContext
            xmlns:wscoor="http://schemas.xmlsoap.org/ws/2003/09/wscoor"
            SOAP:mustUnderstand="true">
            <wscoor:Identifier>
                http://example.com/context/1234
            </wscoor:Identifier>
        </wscoor:CoordinationContext>
    </SOAP:Header>

    <!-- Body with message content -->
    <SOAP:Body>
        <m:aMethodRequest xmlns:m="http://example.com/soap.wsdl">
            <aNumber xsi:type="xsd:int">42</aNumber>
        </m:aMethodRequest>
    </SOAP:Body>

</SOAP:Envelope>

The SOAP standard also introduces a data model, which allows describing simple and compound types, as well as encoding rules, which allow encoding graphs of typed data. Unfortunately, the data model is not explicitly related to XML Schema, which is used to describe simple and compound types in WSDL. Encoding of types described using XML Schema therefore does not necessarily pass validation using the same XML Schema. This discrepancy makes it difficult to validate a SOAP encoded message given the WSDL description of the service for which the message is intended.

Many technologies prefer literal to encoded messages, with the language binding defined directly between the XML Schema in WSDL and the implementation language, rather than between the SOAP data model and the implementation language. This is the case of JAX-RPC and JAX-WS with JAXB.

2.21.2. WSDL

The WSDL standard by W3C defines a web service description in XML. For each service, the description specifies all the data types and message formats used by the service, the message encoding and the communication protocol supported by the service, and the network addresses of the service. The description thus provides all the information that is required to set up communication with the service.

Service Example

<?xml version="1.0"?>
<definitions name="StockQuote"
             targetNamespace="http://example.com/stockquote.wsdl"
             xmlns:tns="http://example.com/stockquote.wsdl"
             xmlns:xsd="http://example.com/stockquote.xsd"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns="http://schemas.xmlsoap.org/wsdl/">

    <!-- Types used in communication -->
    <types>
        <schema targetNamespace="http://example.com/stockquote.xsd"
                xmlns="http://www.w3.org/2000/10/XMLSchema">
            <element name="TradePriceRequest">
                <complexType>
                    <all>
                        <element name="tickerSymbol" type="string"/>
                    </all>
                </complexType>
            </element>
            <element name="TradePriceReply">
                 <complexType>
                     <all>
                         <element name="price" type="float"/>
                     </all>
                 </complexType>
              </element>
          </schema>
      </types>

    <!-- Messages exchanged in communication -->
    <message name="GetLastTradePriceInput">
        <part name="body" element="xsd:TradePriceRequest"/>
    </message>
    <message name="GetLastTradePriceOutput">
        <part name="body" element="xsd:TradePriceReply"/>
    </message>

    <!-- Ports available in communication -->
    <portType name="StockQuotePortType">
        <operation name="GetLastTradePrice">
            <input message="tns:GetLastTradePriceInput"/>
            <output message="tns:GetLastTradePriceOutput"/>
        </operation>
    </portType>

    <!-- Bindings used in communication -->
    <binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
        <soap:binding
            style="document"
            transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetLastTradePrice">
            <soap:operation soapAction="http://example.com/GetLastTradePrice"/>
            <input><soap:body use="literal"/></input>
            <output><soap:body use="literal"/></output>
        </operation>
    </binding>

    <!-- Service -->
    <service name="StockQuoteService">
        <documentation>Stock quoter service.</documentation>
        <port name="StockQuotePort" binding="tns:StockQuoteSoapBinding">
            <soap:address location="http://example.com/stockquote"/>
        </port>
    </service>

</definitions>

<!-- Example adjusted from WSDL 1.1 Specification. -->

The example specifies that the service is accessible using SOAP over HTTP with the document style binding. The document style binding imposes no restriction on the SOAP message structure. An alternative RPC style binding requires that the SOAP message body contains a single procedure element with multiple argument elements as children, the element names are the procedure and argument names.

2.21.3. BPEL

The BPEL standard by OASIS defines a language for service orchestration. Orchestration is described by connecting primitive activities through structured activities. Primitive activities are wait for request, send reply, invoke service, assign variable, throw exception, delay. Structured activities are synchronous sequence, parallel flow, switch, while.

BPEL Example

<process name="anExampleProcess">

    <!-- Partners of the example process -->
    <partnerLinks>
        <partnerLink name="client"
            partnerLinkType="aClientPort"
            myRole="aProviderRole"/>
        <partnerLink name="serverOne"
            partnerLinkType="aServerPort"
            myRole="aClientRole"
            partnerRole="aServerRole"/>
        <partnerLink name="serverTwo"
            partnerLinkType="aServerPort"
            myRole="aClientRole"
            partnerRole="aServerRole"/>
    </partnerLinks>

    <!-- Internal variables -->
    <variables>
        <variable name="clientRequest" messageType="RequestMessage"/>
        <variable name="serverOneResponse" messageType="ResponseMessage"/>
        <variable name="serverTwoResponse" messageType="ResponseMessage"/>
        <variable name="providerResponse" messageType="ResponseMessage"/>
    </variables>

    <!-- Process definition -->
    <sequence>
        <!-- Get the request from the client -->
        <receive partnerLink="client"
            portType="aClientPort"
            operation="GetOffer"
            variable="clientRequest"
            createInstance="yes"/>

        <!-- Forward the request to both servers -->
        <flow>
            <invoke partnerLink="serverOne"
                portType="aServerPort"
                operation="GetOffer"
                inputVariable="clientRequest"
                outputVariable="serverOneResponse"/>
            <invoke partnerLink="serverTwo"
                ... />
        </flow>

        <!-- Create response from cheapest offer -->
        <switch>
            <case condition="bpws:getVariableData ('serverOneResponse','price')
                             <
                             bpws:getVariableData ('serverTwoResponse','price')">
                <assign>
                    <copy>
                        <from variable="serverOneResponse"/>
                        <to variable="providerResponse"/>
                    </copy>
                </assign>
            </case>
            <otherwise>
                ...
            </otherwise>
        </switch>

        <!-- Return the response to the client -->
        <reply partnerLink="client"
            portType="aClientPort"
            operation="GetOffer"
            variable="providerResponse"/>
    </sequence>
</process>