Web Services Interoperability and SOAP

Keith Ballinger
Microsoft Corporation

May 1, 2001

Summary: This article presents an overview and practical introduction to current interoperability issues relating to RPC calls with SOAP. Three sources of interop problems are discussed: HTTP problems, XML issues, and SOAP discontinuities. (7 printed pages)

Contents

Introduction
What Is SOAP?
Common Interop Problems
Transport Problems
XML Problems
SOAP Problems
The Future

Introduction

A number of platforms currently exist for creating applications. Each of these platforms has traditionally used its own protocols, usually binary in nature, for machine-to-machine integration. As a result, applications across platforms have only a limited ability to share data. In recognition of these limitations, there has been an overwhelming push towards standards for data formats and for data exchange. This push stems from a vision that is rapidly evolving into a new computing paradigm: the seamless, Web-enabled integration of services across traditional hardware and software barriers.

At the heart of this vision is the concept of interoperability ("interop" for short), or the capacity of disparate systems to communicate and to share data seamlessly. This is the goal of Web Services. A Web Service is a programmable application logic accessible using standard Internet protocols, or to put it another way, the implementation of Web-supported standards for transparent machine-to-machine and application-to-application communication.

A number of Web Services technologies, such as SOAP (Simple Object Access Protocol), WSDL (Web Service Description Language), and HTTP (HyperText Transfer Protocol), are now used to pass messages between machines. These messages can range widely in complexity, from method calls to purchase order submissions. One common, higher-level function of a Web Service is to implement RPC-style communication (remote procedure call, whereby a program on one computer executes a program on another). This article presents a practical introduction to common interop issues seen today in RPC-style communication using SOAP. Messaging with SOAP, WSDL, and other protocols may be the subject of future articles.

Web Services Road Map

Figure 1. Roadmap of Web Services: wire protocol elements, service description, and discovery

What Is SOAP?

SOAP is the Simple Object Access Protocol. The current version is 1.1, and the actual specification can be found at www.w3.org/tr/soap. SOAP is based on XML and describes a messaging format for machine-to-machine communication. It also contains several optional sections describing method calls (RPC) and detailing the sending of SOAP messages over HTTP. (For more background on SOAP and Web Services, see "A Platform for Web Services.")

Here is a typical SOAP request (including the HTTP headers) for an RPC method call named EchoString, which takes a string as a parameter:

POST /test/simple.asmx HTTP/1.1
Host: 131.107.72.13
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://soapinterop.org/echoString"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:echoString>
      <inputString>string</inputString>
    </tns:echoString>
  </soap:Body>
</soap:Envelope>

As you can see, the method name is encoded as the XML: <tns:echoString>, and the string parameter is encoded as <inputString>. The C# method that this represents looks like this:

public String echoString(String inputString);

And here is the response from the server:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:echoStringResponse>
      <Return>string</Return>
    </tns:echoStringResponse>
  </soap:Body>
</soap:Envelope>

The rules for serializing the string datatype, as well as the method call shape, are defined in SOAP 1.1, sections 5 and 7 (www.w3.org/tr/soap).

Common Interop Problems

Interop problems when performing RPC-style SOAP messaging can arise for a number of reasons. Interestingly, many the interop problems are not SOAP issues per se, but interop issues with the underlying transport or XML engines. In other words, interop problems can be:

  • HTTP problems

  • XML issues, or

  • SOAP discontinuities

It should also be said that the authors of these specs are not perfect, and sometimes ambiguities exist that make it very difficult to determine a single correct behavior.

Transport Problems

At the core of any XML Web Services message is the transport used to send the message. When making RPC calls over SOAP, HTTP is by far the most popular transport. This means that HTTP interop must exist between SOAP stacks.

A simple example of an HTTP interop problem involves the use of SOAPAction. SOAPAction is an HTTP header that must be present in SOAP messages over HTTP. This header can be assigned many different values, such as:

SOAPAction: "http://tempuri.org/"

The value of SOAPAction must be quoted, although completely null is allowed:

SOAPAction:

The problem here is this: If a server requires this null-value SOAPAction, some clients will be unable to comply, for not all HTTP client APIs have a way of setting a null HTTP header value. Two possible solutions are: fix the client APIs, and/or be certain servers don't require a null-value SOAPAction. In general, the only way to avoid problems such as this is to ensure that the HTTP API used is one that is robust and already known to work across the Web. Even so, such issues can still arise, and testing may be the only way to discover them.

XML Problems

The second set of possible interop issues are those involving XML parsing and XSD schema handling. SOAP uses XML and XML Schemas at its core, so interoperable handling of both is requisite for SOAP interop.

An interesting example of an interop issue involving both XML parsing and HTTP transports relates to the Byte Order Mark, or BOM. When sending data over HTTP, you can specify the encoding of the data, such as UTF-16 or UTF-8, in the Content-Type header. You can also indicate the encoding of a piece of XML by inserting a set of bytes that specify the encoding used. When sending UTF-16, the BOM is needed, even if the encoding is present in the Content-Type header (to indicate big-endian or little-endian), but for UTF-8 it is unnecessary. For instance:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

n++<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:echoStringResponse>
      <Return>string</Return>
    </tns:echoStringResponse>
  </soap:Body>
</soap:Envelope>

The first three characters here are hex for the Byte Order Mark indicating UTF-8, but as you can see, the Content-Type also stated this. Some implementations send the BOM for UTF-8, even though they don't need to. Others are unable to process XML with any BOM. The solution here is to avoid sending it unless needed, and to correctly handle it. The correct handling of BOM is essential in processing UTF-16 messages, as BOM is required in this case. Although there is no single way to resolve such issues ahead of time, the best solution once issues are recognized is to refer to the actual specifications (usually found at the W3C) that describe the standards; then apply those specifications as the arbiter of any problem.

SOAP Problems

Now we come to the heart of the matter: SOAP issues themselves. As discussed above, interop for SOAP first requires that transport (usually HTTP) and XML problems be overcome. Once this is accomplished, SOAP issues can be addressed.

SOAP itself is relatively simple. It requires that messages be put into an envelope, with the meat of the message inside a body element. SOAP makes optional such items as headers, and gives leeway as to what can go into the body element. Here is an example of a simple SOAP message that most stacks wouldn't have a problem interoperating with:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body >
    <foo />
  </soap:Body>
</soap:Envelope>

This isn't very interesting, but SOAP also provides for a way to encode common data types (see Section 5 of the SOAP specifications), and it further describes how to encode RPC method calls. As you may remember from the earlier example, method names become child tags of the body, and arguments become child tags of the method name.

Yet even without this extra complexity, a variety of interesting interop problems can be found. For instance, SOAP specifications state that if you receive a SOAP header with a mustUnderstand attribute set to "1," you must understand it, or fault. Many implementations didn't do this at first. Here is an example of a mustUnderstand header:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

n++<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
   <Foo SOAP-ENV:mustUnderstand="1">
          Hello!
   </Foo>
</SOAP-ENV:Header>
  <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <tns:echoStringResponse>
      <Return>string</Return>
    </tns:echoStringResponse>
  </soap:Body>
</soap:Envelope>

This sample is one of the many issues discovered through SOAP interoperability testing. More examples of interop problems that we have seen can be viewed in the archives of http://groups.yahoo.com/group/soapbuilders. Overall, the work done on this list and across the world to make sure that SOAP interoperates when implementing RPC-style communications has been an outstanding success. From May 8th through May 10th, in Las Vegas at Networld+Interop, many in the SOAP community will be gathering to demonstrate this success. If you have a SOAP stack, or are just curious, come by and check out the demos.

Also, much of the XML Web Services discussion and testing has been taking place at http://groups.yahoo.com/group/soapbuilders, http://www.mssoapinterop.org/, and http://www.xmethods.net/ilab/. These sites contain links to many endpoints for interop testing. Anyone building a SOAP stack is encouraged to read the archive and participate in the interop testing.

The Future

This article briefly outlines some of the early interop problems found in the XML Web Services world. This isn't the end of the line, however. There are many more interesting scenarios with SOAP that still need to be covered beyond RPC over HTTP. These include "document"-style message passing, SOAP over SMTP and other transports, WSDL, and various SOAP header tests - all worthwile subjects for discussion in future articles.



© 2001 Microsoft Corporation. All rights reserved. Terms of use.