Selecting the Best Approach for Designing an Interoperable Web Service

Summary

Web Services technology is well established as a communication technology for the Internet, offering greatest interoperability. Their standardization process is going on at great speed, which will lead to even broader acceptance. Nevertheless, judging from mailing lists and user groups, discussions there say that there is still quite a lot of confusion about the different Web Services Design approaches. What does "Document/Literal" mean compared to "RPC-style?" How does SOAP "message-style" fit into this?

This article will clarify and explain in detail the different Web Service Design Methodologies as defined by the Web Services Standardization Groups, clarify the terms, and highlight their differences. It will be focus on the following Web Services Design Approaches evaluate their strengths and weaknesses and explore how far each style supports in designing an Interoperable Web Service.

  1. RPC/Encoded Style
  2. RPC/Literal Style
  3. Document/Literal Style
  4. Document/Literal Wrapped Style

Introduction

In their relatively short time of existence, Web Services have gained an enormous acceptance and a broad usage on the market. One reason for this surely is their very early open standardization that has been driven by all major players on the market. On the other side, all these players also have their preferences on how Web Services should look and how they should communicate. This, and the fact that different communication styles are required, has led to standards that today support different ways of how Web Services messages can be formatted and how they can communicate.

The relevant standards for describing and using Web Services are the Web Services Description Language (WSDL), a standardized XML Schema-like language that is used for specifying a Web Service and the Simple Object Access Protocol (SOAP), the actual communication protocol for Web Services ([WSDL] and [SOAP]).

Before moving to the real design approaches, let's clarify some of the terms that are frequently used in the world of Web Services.

Communication Patterns

I'll start with the communication patterns. With Web Services, you can essentially distinguish three different ways of communication:

  • Remote procedure call: Client sends a SOAP request to the service provider and then waits for a SOAP response (synchronous communication).
  • Messaging: Client sends a SOAP request and expects no SOAP response back (one-way communication)
  • Asynchronous callback: A client calls the service with one of the above methods. Later, the two parties switch roles for a callback call. This pattern can be built from either of the first two.

SOAP Formatting Rules

Now, you can turn to how the SOAP message of a Web Service can be formatted (essentially the message's <soap:body> element). WSDL 1.1 distinguishes two different binding styles (referred to as soap:binding styles): RPC and Document.

  • RPC Style: The RPC style specifies that the <soap:body> contains an element with the name of the Web method being invoked (wrapper element). This element in turn contains an entry for each parameter and the return value of this method.
  • Document Style: If the style is of the document type, there is no wrapper element as with the RPC style. Instead, the message parts appear directly under the <soap:body> element. There are no SOAP formatting rules for what the <soap:body> contains; it contains what the sender and receiver agreed upon as an XML document.

The second formatting rule is the 'Use' attribute. This concerns how types are represented in XML. It indicates whether the message parts are encoded using some encoding rules, or whether the parts define the concrete schema of the message. The two offered choices are:

  • Encoding: If the use is encoded, each message part references an abstract type using the type attribute. The message is produced using an encoding specified by the encodingStyle attribute. The mostly used SOAP Encoding is a set of serialization rules defined in SOAP 1.1. The rules specify how objects, structures, arrays, and object graphs should be serialized. In general, the applications using SOAP encoding are focused on remote procedure calls and will likely use the RPC message style.
  • Literal: If the use is Literal, each part references a concrete schema definition using either the element or type attribute; in other words, data is serialized according to a given schema. In practice, this schema is usually expressed using W3C XML Schema.

Table 1 summarizes the options for different Web Services parameters. An important realization is that three independent decisions are to be made by a Web Services developer. What is the "Communication Pattern" to be used? What is the SOAP formatting "Style" to be used? And finally, what is the SOAP message encoding Type to be used?

Table 1: Web Services Parameters

WSDL Parameters Available Options
Communication Patterns Remote Procedure Call or One-way messaging
Style Document or RPC
Use Encoded or Literal

Although, in theory, any combination of these options is possible, in practice there is a clear preference of one combination over the other, and also the standards and the Web Services Interoperability organization (WS-I) has a clear preference.

Thus, in practice, only Document/Literal and RPC/Encoded have gained widespread usage and are directly supported by most platforms as indicated in Table 2. The table shows also the results of the WS-I conformance tests for the different style/use combinations.

Table 2: Web Services Format Support

Style/Use Combination Supported SOAP Toolkit WS-I Conformance
RPC/Encoded Microsoft, Axis 1.1 Failed
RPC/Literal Axis 1.1 Failed
Document/Literal Microsoft, Axis 1.1 Passed

The Document/Encoded format has not been tested because it is not supported by the platforms used. In fact, there is no real-world usage of the Document/Encoded combination.

A Simple Web Service Example

Now, look in more detail into the mostly used and supported style/use formats RPC/Encoded and Document/Literal. I will illustrate each of these style use combinations by means of a Web method called "SendTemperature" that takes a user-defined complex object as its parameter and returns a void type, as described in Listing 1.

I chose an example with a complex data type to make the differences between the various styles more obvious.

Listing 1: SendTemperature Web method implemented in C#

public void SendTemperature (Temperature[] TempCollection){}

public class Temperature
{
   /// <remarks/>
   public int Id;

   /// <remarks/>
   public string Name;

   /// <remarks/>
   public System.Double Temperature;
}

You will see how the various Web Services formats are implemented in the WSDL file for this Web method with their respective SOAP request formats and their differences will be highlighted. The implementations were done using Microsoft VS.NET and the Axis SOAP toolkit.

Note that the namespaces, prefixes, and the service part of the WSDL files that follows in this article have been ignored for simplicity. Listing 2 shows the common namespaces and prefixes that were used.

Listing 2: Namespaces and used prefixes

xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://interop.webservices.fhso.ch/{service name}"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://interop.webservices.fhso.ch/{service name}/"

Selecting the Best Approach for Designing an Interoperable Web Service

1. RPC/Encoded Style

RPC/Encoded is essentially a format following the classical "remote procedure call" style in which a client sends a synchronous request to a server to execute an operation. The SOAP request contains the name of method to be executed and the parameter it takes. The server running the Web Service converts this request to appropriate objects, executes the operation, and sends the response back to the client as a SOAP message. At the client side, this response is used to form appropriate objects and return the required information to the client. In RPC-style Web Services, the complete method is specified in the WSDL file and in the SOAP body, including the sent parameters and the return values. So, you have a rather tight coupling with this style.

Listing 3 shows the WSDL defined for the SendTemperature Method in the RPC/Encoded style.

Listing 3: RPC/Encoded WSDL for SendTemperature

<types>
      <s:schema targetNamespace="http://interop.webservices.fhso.ch/
                                        rpcencoded">
         <s:complexType name="ArrayOfTemperature">
            <s:complexContent mixed="false">
               <s:restriction base="soapenc:Array">
                  <s:attribute d7p1:arrayType="s0:Temperature[]"
                     ref="soapenc:arrayType"
                     xmlns:d7p1="http://schemas.xmlsoap.org/wsdl/"/>
               </s:restriction>
            </s:complexContent>
         </s:complexType>
         <s:complexType name="Temperature">
            <s:sequence>
               <s:element minOccurs="1" maxOccurs="1" name="Id"
                          type="s:int"/>
               <s:element minOccurs="1" maxOccurs="1" name="Name"
                          type="s:string"/>
               <s:element minOccurs="1" maxOccurs="1" name="value"
                          type="s:double"/>
            </s:sequence>
         </s:complexType>
      </s:schema>
   </types>
   <message name="SendTemperatureSoapIn">
      <part name="Collection" type="s0:ArrayOfTemperature"/>
   </message>
   <message name="SendTemperatureSoapOut"/>
   <portType name="TemperatureRpcEncodedSoap">
      <operation name="SendTemperature">
         <input message="s0:SendTemperatureSoapIn"/>
         <output message="s0:SendTemperatureSoapOut"/>
      </operation>
   </portType>
   <binding name="TemperatureRpcEncodedSoap"
            type="s0:TemperatureRpcEncodedSoap">
      <soap:binding style="rpc"
                    transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="SendTemperature">
         <soap:operation soapAction="http://interop.fhso.ch/soapformat/
                                            SendTemperature"/>
         <input>
            <soap:body use="encoded"
                       encodingStyle="http://schemas.xmlsoap.org/
                                             soap/encoding/"/>
         </input>
         <output>
            <soap:body use="encoded"
                       encodingStyle="http://schemas.xmlsoap.org/
                                             soap/encoding/"/>
         </output>
      </operation>
   </binding>

Notice the binding style, which is set to 'rpc' and use, which is set to 'encoded'. Under the <message> section, there can be any number of <part> elements, each containing a type attribute that is unique to the 'rpc' style. Now, look at what happens when you invoke the SendTemperature Web method, sending an array with two entries. Listing 4 shows the resulting SOAP message.

Listing 4: RPC/Encoded SOAP Message for SendTemperature

<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/
              xmlns:tns="http://interop.webservices.fhso.ch/rpcencoded"
              xmlns:types="http://interop.webservices.fhso.ch/
                                  rpcencoded/encodedTypes"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/
                                         encoding/">
      <SendTemperature>
         <Collection href="#id1"/>
      </SendTemperature>
      <soapenc:Array id="id1" soapenc:arrayType="tns:Temperature[2]">
         <Item href="#id2"/>
         <Item href="#id3"/>
      </soapenc:Array>
      <tns:Temperature id="id2" xsi:type="tns:Temperature">
         <Id xsi:type="xsd:int">3</Id>
         <Name xsi:type="xsd:string">Station1</Name>
         <value xsi:type="xsd:double">34.3</value>
      </tns:Temperature>
      <tns:Temperature id="id3" xsi:type="tns:Temperature">
         <Id xsi:type="xsd:int">56</Id>
         <Name xsi:type="xsd:string">Station3</Name>
         <value xsi:type="xsd:double">23.6</value>
      </tns:Temperature>
   </soap:Body>
</soap:Envelope>

Each parameter is type encoded in the SOAP message. Also notice the 'href' tags in the SOAP message, which is an essential part of the RPC/Encoded style and which is used to reference the items in the array. Under any literal style, the 'href' tag is not available. Let's analyze the WSDL and its SOAP message format.

Strengths:

  • The definition of the WSDL file follows the intuitive and well-known remote-procedure-call style.
  • The operation name appears in the message, so that the receiver has an easy time dispatching the message to its implementation.
  • If you are using data graphs or polymorphism in your service, this is the only possible style that can be used for the types described in this article.

Weaknesses:

  • The SOAP message includes the type encoding information such as xsi:type="xsd:int", xsi:type="xsd:string", xsi:type="xsd:double", which is an overhead.
  • In general, it is harder to validate the SOAP message.
  • The RPC style causes a rather tight coupling between service provider and client. Any changes to the interface would break the contract between the service and the client.
  • Depending on the information that may need to be handled simultaneously, memory constraints may make RPC messaging unfeasible because marshalling takes place in-memory.
  • Is not supported by the WSI conformance standard.

Now, look at the implementation of the same Web method in RPC/Literal format and see whether it can eliminate some of the drawbacks of the RPC/Encoded style.

2. RPC/Literal Style

The WSDL looks almost similar to the previous one except the change in the 'use' setting from 'encoded' to 'literal' in the soap:body as shown in Listing 5. As described above, this means that the data type definition is not provided by the referenced XML Schema instead of RPC encoding.

Listing 5: RPC/Literal WSDL for SendTemperature

<types>
      <s:schema elementFormDefault="qualified"
                targetNamespace="http://interop.webservices.fhso.ch/
                                        rpcliteral">
         <!-- there are no global element declarations. There's
              nothing in the schema that completely describes the
              content of soap:Body -->
         <s:complexType name="ArrayOfTemperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="unbounded"
                          name="Temperature" nillable="true"
                          type="s0:Temperature"/>
            </s:sequence>
         </s:complexType>
         <s:complexType name="Temperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="1" name="Id"
                          type="s:int"/>
               <s:element minOccurs="0" maxOccurs="1" name="Name"
                          type="s:string"/>
               <s:element minOccurs="0" maxOccurs="1" name="value"
                          type="s:double"/>
            </s:sequence>
         </s:complexType>
      </s:schema>
   </types>
   <message name="SendTemperatureSoapIn">
      <part name="Collection" type="s0:ArrayOfTemperature"/>
   </message>
   <message name="SendTemperatureSoapOut"/>
   <portType name="TemperatureRpcLiteralSoap">
      <operation name="SendTemperature">
         <input message="s0:SendTemperatureSoapIn"/>
         <output message="s0:SendTemperatureSoapOut"/>
      </operation>
   </portType>
   <binding name="TemperatureRpcLiteralSoap"
            type="s0:TemperatureRpcLiteralSoap">
      <soap:binding style="rpc"
                    transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="SendTemperature">
         <soap:operation soapAction="http://interop.fhso.ch/soapformat/
                                            SendTemperature"/>
      <input>
            <soap:body use="literal"
                       namespace="http://interop.fhso.ch/soapformat/
                                         SendTemperature"/>
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
   </binding>

However there is still a major drawback with this style. The XML Schema alone does not tell you what the message body Infoset contains; you must also know the RPC rules. Therefore, the schema describing an RPC/Literal message is not sufficient to validate that message.

Now, look at the SOAP message format for RPC/Literal shown in Listing 6. Note that the type encoding is completely removed.

Listing 6: RPC/Literal SOAP message for SendTemperature

<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
< ! - SendTemperature is the name of the procedure being invoked.
Collection is a parameter of that procedure.
Note that Collection is not namespace qualified. The two Temperature
elements are contents of the Collection parameter. This Collection
can be thought of as an array of Temperature items. Note that the
Temperature is namespace qualified but is in a different namespace
than SendTemperature. These namespace rules are unique to RPC-style
messages -- >
      <SendTemperature xmlns="http://interop.fhso.ch/soapformat/
                                     SendTemperature">
         <Collection xmlns="">
            <ns1:Temperature
               xmlns:ns1="http://interop.webservices.fhso.ch/
                                 rpcliteral">
               <ns1:Id>2</ns1:Id>
               <ns1:Name> Station1</ns1:Name>
               <ns1:value>34.2</ns1:value>
            </ns1:Temperature>
            <ns2:Temperature
               xmlns:ns2="http://interop.webservices.fhso.ch/
                                 rpcliteral">
               <ns2:Id>56</ns2:Id>
               <ns2:Name> Station 3</ns2:Name>
               <ns2:value>23.6</ns2:value>
            </ns2:Temperature>
         </Collection>
      </SendTemperature>
   </soapenv:Body>
</soapenv:Envelope>

Strengths:

  • The WSDL is still about as straightforward as with the RPC/Encoded style
  • The operation name still appears in the SOAP message
  • The type encoding is eliminated from the message and hence increases the throughput performance

Weaknesses:

  • The contract between the service and the clients are still tightly coupled.
  • It is still hard to validate the transferred data by the SOAP message.
  • Is not supported by the WSI conformance standard either

Now, you can move to the Document/Literal type and see whether this style can reduce the existing drawbacks.

Selecting the Best Approach for Designing an Interoperable Web Service

3. Document/Literal

The major difference of the Document style to the above RPC styles is that the client sends the service parameters in a normal XML document to the server, instead of a discrete set of parameter values of methods. This makes the Document style a more loosely coupled style of interaction than the RPC format.

The Web Service provider processes the normal XML document, executes the operation, and sends the response to the client again as a normal XML document. There is no direct mapping between the server objects (parameters, method calls, and so forth) and the values in XML documents. The application is responsible for mapping the XML data values. The SOAP message of a Document style carries one or more XML documents within its SOAP body. The protocol places no constraint on how the document needs to be structured; this is completely handled at the application level. Additionally, Document style Web Services follow the asynchronous processing paradigm.

The WSDL for this style has more changes compared to the RPC style, as shown in Listing 7.

Listing 7: Document/Literal WSDL for SendTemperature

<types>
      <s:schema elementFormDefault="qualified"
                targetNamespace="http://interop.webservices.fhso.ch/
                                        docLit">
         < ! - - This element declaration describes the entire
                    contents of the soap:Body in the request message.
                    This is a feature of document/Literal that
                    RPC/Literal lacks - -> 
         <s:element name="Collection">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="unbounded"
                             name="Temperature" nillable="true"
                             type="s0:Temperature"/>
               </s:sequence>
            </s:complexType>
         </s:element>
         <s:complexType name="Temperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="1" name="Id"
                          type="s:int"/>
               <s:element minOccurs="0" maxOccurs="1" name="Name"
                          type="s:string"/>
               <s:element minOccurs="0" maxOccurs="1" name="value"
                          type="s:double"/>
            </s:sequence>
         </s:complexType>
      < ! - Similarly, this element declaration describes the
            contents of the SOAP body in the response message.
            In this case, the response is empty. -- > 
         <s:element name="SendTemperatureResponse">
            <s:complexType/>
         </s:element>
      </s:schema>
   </types>
   <message name="SendTemperatureSoapIn">
      <part name="parameters" element="s0:Collection"/>
   </message>
   <message name="SendTemperatureSoapOut">
      <part name="parameters" element="s0:SendTemperatureResponse"/>
   </message>
   <portType name="TemperatureDocLitSoap">
      <operation name="SendTemperature">
         <input message="s0:SendTemperatureSoapIn"/>
         <output message="s0:SendTemperatureSoapOut"/>
      </operation>
   </portType>
   <binding name="TemperatureDocLitSoap"
            type="s0:TemperatureDocLitSoap">
      <soap:binding style="document"
                    transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="SendTemperature">
         <soap:operation
            soapAction="http://interop.webservices.fhso.ch/
                               documentliteral/SendTemperature"
            style="document"/>
         <input>
            <soap:body use="literal"/>
         </input>
         <output>
            <soap:body use="literal"/>
         </output>
      </operation>
   </binding>

Note that the binding style is set to 'document' and use to 'literal'. Under the 'message' section, only a single <part> element is possible, which contains an element attribute.

This part points to a schema element declaration that describes the entire contents of the SOAP body. Note that the Collection is now defined as an element rather that a type. The primary feature of Document/Literal, and its key benefit compared to RPC/Literal, is the use of the schema element declaration to completely describe the contents of the <soap:body>. This means that you can tell what the message body Infoset contains just by looking at the schema with no need for additional rules. Consequently, you could take the schema describing a Document/Literal message and use it to validate the message; you can't do this with RPC/Literal.

Now, look at the corresponding SOAP message format shown in Listing 8. Note that there is no type encoding data specified and that the operation name is missing.

Listing 8: Document/Literal SOAP message for SendTemperature

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
   < -- Note that the Operation name is missing in the message -- >
      <Collection xmlns="http://interop.webservices.fhso.ch/docLit">
         <Temperature>
            <Id>2</Id>
            <Name>Station 1</Name>
            <value>34.2</value>
         </Temperature>
         <Temperature>
            <Id>56</Id>
            <Name>Station 3</Name>
            <value>23.5</value>
         </Temperature>
      </Collection>
   </soap:Body>
</soap:Envelope>

The summarized strengths and weaknesses of this approach are as follows.

Strengths:

  • No type encoding information in the SOAP message.
  • You can always validate the message with any XML validator. Everything within the SOAP body is defined in the schema.
  • With document style, the rules are less rigid and many enhancements and changes can be made to the XML schema without breaking the interface.
  • Document style services can maintain the application state if multiple procedures must be called in a particular sequence.
  • Document style is better suited for asynchronous processing.
  • Many document-messaging services are able to choose between DOM and SAX handlings of the document and as a result are able to minimize in-memory processing

Weaknesses:

  • The WSDL is getting bit more complicated.
  • The operation name in the in the SOAP message is lost. Without the name, the dispatching can be difficult or impossible.

You have seen that the Document/Literal style eliminates most of the drawbacks of the RPC/Literal style; on the other side, it introduces a new one: It loses the operation name in the SOAP message.

Because the fourth format option, Document/Encoding, has no practical usage, it will not be described. Instead, you will see an extension to the Document/Literal style, the Document/Literal wrapped format.

4.Document/Literal wrapped

This style has been suggested by Microsoft to fix the drawback from the standard Document/Literal style. Although there is no specification in the WSDL 1.1 standard for this style, many current SOAP toolkits support it.

First, look at the WSDL in Listing 9 and its corresponding SOAP message in Listing 10.

Listing 9: Document/Literal wrapped WSDL for SendTemperature

<types>
      <s:schema elementFormDefault="qualified"
                targetNamespace="http://interop.webservices.fhso.ch/
                                        docLitWrapped">
         <s:element name="SendTemperature">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1"
                             name="Collection"
                             type="s0:ArrayOfTemperature"/>
               </s:sequence>
            </s:complexType>
         </s:element>
         <s:complexType name="ArrayOfTemperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="unbounded"
                           name="Temperature" nillable="true"
                           type="s0:Temperature"/>
            </s:sequence>
         </s:complexType>
         <s:complexType name="Temperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="1" name="Id"
                          type="s:int"/>
               <s:element minOccurs="0" maxOccurs="1" name="Name"
                          type="s:string"/>
               <s:element minOccurs="0" maxOccurs="1" name="value"
                          type="s:double"/>
            </s:sequence>
         </s:complexType>
         <s:element name="SendTemperatureResponse">
            <s:complexType/>
         </s:element>
      </s:schema>
</types>
   <message name="SendTemperatureSoapIn">
      <part name="parameters" element="s0:SendTemperature"/>
   </message>
   <message name="SendTemperatureSoapOut">
      <part name="parameters" element="s0:SendTemperatureResponse"/>
   </message>
   <portType name="TemperatureDocLitWrappedSoap">
      <operation name="SendTemperature">
         <input message="s0:SendTemperatureSoapIn"/>
         <output message="s0:SendTemperatureSoapOut"/>
      </operation>
   </portType>
   <binding name="TemperatureDocLitWrappedSoap"
            type="s0:TemperatureDocLitWrappedSoap">
      <soap:binding style="document"
                    transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="SendTemperature">
<soap:operation soapAction="http://interop.webservices.fhso.ch/
                                      docLitWrapped/SendTemperature"
                   style="document"/>
         <input>
            <soap:body use="literal"/>
         </input>
         <output>
            <soap:body use="literal"/>
         </output>
      </operation>
   </binding>

First, notice in Listing 9 that the operation name is now reintroduced into the WSDL file in the first 'element' tag. Also, notice that this SOAP message in Listing 10 looks similar to the RPC/Literal SOAP Message. But, there is a subtle difference. In the RPC Literal SOAP message, the <SendTemperature> child of <soap:body> was the name of the operation. In the Document/literal wrapped soap message, the <SendTemperature> is the name of the element to which the single input message's part refers. This pattern is a sly way of putting the operation name back into the SOAP message.

These are the characteristics of the Document/Literal wrapped pattern:

  • The input message has a single part.
  • The part is an element.
  • The element has the same name as the operation.
  • The element's complex type has no attributes.

Listing 10: Document/Literal wrapped message for SendTemperature

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
<! - The following is an XML document described in the service's
     contract using XML schema. In this case, SendTemperature may
     or may not be the name of the remote procedure being invoked
     by this message.
     Also, Collection may or may not be the name of the parameter.
     We know the structure of the XMLl document but we don't know
     how the service is going to process it. -- >
      <SendTemperature
         xmlns="http://interop.webservices.fhso.ch/docLitWrapped">
         <Collection>
            <Temperature>
               <Id>2</Id>
               <Name>Station 1</Name>
               <value>34.2</value>
            </Temperature>
            <Temperature>
               <Id>56</Id>
               <Name>Station 3</Name>
               <value>23.6</value>
            </Temperature>
         </Collection>
      </SendTemperature>
   </soap:Body>
</soap:Envelope>

The summarized strengths and weaknesses of this approach are:

Strengths:

  • Contains all the strengths of Document/Literal style.
  • The method name appears in the SOAP message.

Weaknesses:

  • The WSDL is even more complicated, but this is still a very minor weakness.
  • If you have overloaded operations in your Web Service, you cannot use this style.

So far, you have seen that Document/Literal and Document/Literal wrapped styles brought us a lot of flexibility and strengths compared to any other design style. Yet, there are some issues remaining to be addressed.

Selecting the Best Approach for Designing an Interoperable Web Service

Limitations of the Document/Literal and Document/Literal Wrapped Styles

Suppose you have overloaded operations as shown in Listing 11.

Listing 11: Overloaded SendTemperature Method

public void SendTemperature (Temperature[] TempCollection){}
public void SendTemperature (Temperature[] TempCollection, int week){}

In this situation, it is not possible to use the Document/Literal wrapped style even though the WSDL specification allows you to have overloaded operations. The reason for this is that when you add a wrapped pattern to a WSDL document, you require an element to have the same name as the operation (refer to Listing 9). The issue comes when you want to have two elements with the same name in the XML Schema. So, the alternative you have for overloaded operations is to use Document/Literal non-wrapped or one of the RPC styles.

See how you can realize this in Document/Literal. Here is the modification of the schema section of the WSDL for the above two Web methods.

Listing 12: Changed Schema Section of the Document/Literal WSDL for SendTemperature

<types>
      <s:schema elementFormDefault="qualified"
                targetNamespace="http://interop.webservices.fhso.ch/
                                        docLit">
         <s:element name="Collection">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="unbounded"
                             name="Temperature" nillable="true"
                             type="s0:Temperature"/>
                  <s:element minOccurs="0" maxOccurs="1" name="week"
                             type="s:int"/>
               </s:sequence>
            </s:complexType>
         </s:element>
         <s:complexType name="Temperature">
            <s:sequence>
               <s:element minOccurs="0" maxOccurs="1" name="Id"
                          type="s:int"/>
               <s:element minOccurs="0" maxOccurs="1" name="Name"
                          type="s:string"/>
               <s:element minOccurs="0" maxOccurs="1" name="value"
                          type="s:double"/>
            </s:sequence>
         </s:complexType>
         <s:element name="SendTemperatureResponse">
            <s:complexType/>
         </s:element>
      </s:schema>
   </types>

You just added another element to the Collection; everything else remains similar as in Listing 7. It is interesting to look at the client proxy generated by the VS.NET wsdl.exe utility.

Listing 13: C# proxy code generated for the overloaded SendTemperature

Public void
   SendTemperature([System.Xml.Serialization.XmlElementAttribute
                   ("Protocol", IsNullable=true)] Temperature[]
                    Temperature, int week,
                    [System.Xml.Serialization.XmlIgnoreAttribute()]
                    bool weekSpecified) {
            this.Invoke("SendTemperature", new object[] {
                        Temperature,
                        week,
                        weekSpecified});
        }

Notice that an additional Boolean variable called "weekSpecified" is automatically created and now the client can invoke this operator overloaded web Method in two ways. If a client invokes this method with the week specified set to "false", you call the first overloaded method of Listing 11, and the SOAP request is still identical to the one of Listing 10.

SendTemperature(Temperatue_Object,7,false);

On the other hand, if a client call is made with the weekSpecified set to "true", it refers to the overloaded method of Listing 11, and the now the SOAP request looks like the following with the "week" parameter being passed as an XML tag.

SendTemperature(Temperature_Object,7,true);

Listing 14: SOAP Message for the second overload format.

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <Collection xmlns="http://interop.webservices.fhso.ch/docLit">
         <Temperatue>
            <Id>2</Id>
            <Name>Station 1</Name>
            <value>34.2</value>
         </Temperature>
         <Temperature>
            <Id>56</Id>
            <Name>Station 3</Name>
            <value>23.5</value>
         </Temperature>
         <week>7</week>
      </Collection>
   </soap:Body>
</soap:Envelope>

Now we have seen how the problem with Document/Literal wrapped is nicely solved by the standard Document/Literal.

Conclusion

Document-centric and RPC Web Services fill quite different niches. Document-style Web Services are more suitable for most enterprise-to-enterprise interaction over the Internet. Developing a Document-style Web Service may require little more effort than RPC-style. You saw that the Document/Literal Style and Document/Literal wrapped styles brought a lot of flexibility and strengths in Interoperability compared to any other design style. Any time you are not interfacing to a preexisting RPC, the benefits of the document-style usually outweigh the fact to interface to the service. The RPC/Encoded approach is highly discouraged in designing a Web Service if your main requirement is the interoperability.

The WS-I Basic profile 1.0 discourages the use of RPC/Encoded approach and motivates Document/Literal and RPC/Literal as the only allowed style/use combinations. Many believe that RPC/Literal would go away with the future versions of the WSI profile.

References

[WSI] WS-I Final Specification "BasicProfile Version 1.0a" 8 August 2003. http://www.ws-i.org/Profiles/Basic/2003-08/BasicProfile-1.0a.htm

[WSDL] WSDL Specification. http://www.w3.org/TR/wsdl20/

[SOAP] SOAP Specification. http://www.w3.org/TR/SOAP/

[IBMWS] IBM Developer works Web Services article suite. http://www-136.ibm.com/developerworks/webservices/

[XMETH] Publicly available Web Services in both Doc/RPC styles at Xmethods. http://www.xmethods.com/

[MSDN] Microsoft's MSDN Web Services article library. http://msdn.microsoft.com/webservices/

About the Authors

Nalaka Withanage is an Electronics & Telecommunications Engineer and a Microsoft Certified Solutions Developer for .NET. He has been involved in designing and implementing Web Services-based distributed systems as business solutions over the past 3+ years with J2EE, XML, ASP.NET, C#, VB .NET, and .NET Compact Framework technologies. You can reach him at nwithanage@yahoo.com.

Martin Kropp is a professor of Computer Science at the University of Applied Sciences Solothurn/Northwest Switzerland in Olten. He teaches software engineering with an emphasis on object-oriented technology. He has defined and conducted several research projects for solving real-world problems through distributed systems technology, including .NET and Web Services. You can reach him at martin.kropp@fhso.ch.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The impact of a data loss event can be significant. Real-time data is essential to remaining competitive. Many companies can no longer afford to rely on a truck arriving each day to take backup tapes offsite. For most companies, a cloud backup and recovery solution will eliminate, or significantly reduce, IT resources related to the mundane task of backup and allow your resources to be redeployed to more strategic projects. The cloud - can now be comfortable for you – with 100% recovery from anywhere all …

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds