Interoperability



Interoperability

One of the key reasons to use Web service technologies in a distributed application is interoperability. Just as you can use HTTP and HTML browsers on nearly every operating system and platform on the planet, so too can you use SOAP and WSDL. These technologies enable you build a distributed application and deploy it in a heterogeneous environment of UNIX, Macintosh, mainframe, and Windows platforms. As well, developers of each service and client can use Java, .NET, Perl, and even Smalltalk.

This promise of interoperability isn't as clean as it could be. Just as a Web page will look different in Netscape and Internet Explorer, so too will SOAP messages be sent and read differently by different Web service stacks. However, builders of these stacks have done a lot of work to facilitate interoperability. Not every issue and bug have been fixed, but many scenarios work, and common customers are deploying real SOAP-based applications in heterogeneous environments.

This section deals with some of the design steps you can take early in your project to ensure maximum interoperability. However, the industry is moving very quickly, so consider this section to be in even greater flux than many others. That said, I've tried to focus on common interoperability principles that will apply for many years to come.

Audience-Centered Design

The first thing to realize is that your intended audience should dictate many of the interoperability steps you take. If you are building a service for use by a single partner on a J2EE platform running Linux, then factor that data into your decision up front. If you're exposing a service that an unknown number of people will use on an unknown number of platforms, then your decision will be different.

To begin with, educate yourself about the actual interoperability results that exist between any two platforms. The best way to do that is to review the interoperability results matrix found at http://www.xmethods.net/ilab or http://www.whitemesa.net. Like all URLs, these may not exist by the time you read this (although they've been very stable for the past 2 years). In that case, check my Web site at www.keithba.com/book for the new URLs.

If you are interested in the interoperability results for .NET or other Microsoft SOAP stacks, then also try http://www.mssoapinterop.org. This site contains the actual results for the SOAP Toolkit, ASP.NET Web Services, and .NET Remoting.

Once you know what stack your partner is using, the next step is to review these interoperability results and find a platform with good results that you feel comfortable developing on. For example, if your partner or partners are using ASP.NET Web Services and you are experienced J2EE developers, then Apache Axis or The Mind Electric's GLUE would be a great choice, offering a large amount of interoperability. Alternatively, if your partner is using Systinet's WASP for C++ and you are a Perl shop, then SOAP::lite may be your best choice.

SOAP Platforms and Interoperability

To be honest, I feel there are four SOAP platforms that will always offer you interoperability success: .NET, The Mind Electric's GLUE, Apache Axis, and SOAP::lite. Some have large corporations behind them (Microsoft for .NET; IBM, Macromedia, and several others for Apache Axis), and SOAP::lite is the epitome of interop. I would usually choose one of these four platforms. That said, there are many other platforms that offer success: Systinet's WASP, and Simon Fell's PocketSOAP come to mind instantly. Each of these offers some fantastic features (PocketSOAP works on the PocketPC, for example) while maintaining high interoperability standards.

Once you've decided on a platform, you'll need to design your service to maintain high levels of interoperability. For example, if you are using ASP.NET Web Services and you expose a DataSet object in one of your SOAP operations, then you may find that your partners have a difficult time interoperating. On the other hand, if you are expecting to interoperate only with other .NET platforms, then DataSet offers some excellent features.

As well, several of the decisions you can make will offer various levels of tactical (short-term) versus strategic (long-term) interoperability. The next section deals with those.

Specific SOAP Issues

As of this writing, SOAP interoperability has moved dramatically, and quite far. In particular, there have been a number of advances with respect to interoperability for RPC/encoded style service.

Specifically, the SOAPBuilders Yahoo! Group (http://groups.yahoo.com/group/soapbuilders/) has engaged in a number of rounds of inter-operability testing. Most of the early ones have focused on RPC/encoded SOAP; however, there also has been significant testing of doc/literal, and testing of WSDL. Going to any SOAPBuilders member and examining that member's results against others is usually sufficient research for choosing the right interoperability focus. If you are actually building a SOAP stack, however, it may be useful to think about the various issues that the SOAP-Builders have found.

To begin with, it's important to understand that many SOAP issues actually occur at the basic XML or HTTP level. You need to interoperate at those levels before you can interoperate at the SOAP level.

Typical XML interoperability issues include character set encoding, such as UTF-8 or ASCII, and namespaces and the handling of namespaces. With HTTP, the issues usually are found with HTTP version 1.1 as opposed to HTTP 1.0. There are still several HTTP stacks that either don't do HTTP 1.0, or that do HTTP 1.1 incorrectly. The most common thing to watch out for is lack of keep-alive support.

Most of the problems with Web services interoperability are likely to occur with actual SOAP errors. Section 5 of the SOAP specification, along with Section 7, defines a data encoding that can be used without XML schemas. Even with schemas, Section 5 encoding still is very popular among implementations, but it is also the most likely to be misunderstood and mis-implemented.

For example, Section 5 mentions that you can send the data type of an element with the xsi:type attribute. The message in Listing 15.1 is an example of a method return.

An Example SOAP Message Using xsi:type
<S:Envelope
     xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<S:Body>
<ns1:echoStringResponse
   xmlns:ns1="http://soapinterop.org/"
   S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <return xsi:type="xsd:string">Hello, World</return>
</ns1:echoStringResponse>
</S:Body>
</S:Envelope>

This typing information is required only when the data type is itself a polymorphic one. Of course, polymorphism can be hard to define without some kind of out-of-band agreement; however, assuming that both sides think the parameter is a string, this attribute is not required. A few popular implementations have required typing information, but fortunately most of these implementations have newer versions that no longer require this information except for polymorphic types. This is just an example of the kind of interoperability problems that for the most part no longer exist. However, it is still something to keep in mind.

Another, even more fundamental problem involves document and RPC style interfaces. Some toolkits can do only one or the other, and every toolkit has a different default. Apache SOAP is an RPC/encoded toolkit by default, whereas .NET Web Services is document/literal by default. One of the most common problems I've seen is when an Apache client sends an RPC/encoded request message to a .NET server, and the .NET server returns a response, but that response is the response message you would see from a request message that was full of null values. For example, the message in Listing 15.2 could be sent for a simple Add service.

An Encoded SOAP Message
<S:Envelope
     xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<S:Body>
<ns1:Add
   xmlns:ns1="http://soapinterop.org/"
   S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <A xsi:type="xsd:int">4</A>
      <B xsi:type="xsd:int">4</B>
</ns1:echoStringResponse>
</S:Body>
</S:Envelope>

However, then the response message from the .NET server is null, instead of 8, as shown in Listing 15.3.

A Null Document/Literal Response
<S:Envelope
     xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<S:Body>
<ns1:AddResponse
   xmlns:ns1="http://soapinterop.org/" >
</ns1:AddResponse>
</S:Body>

The problem here is that there was formal communication of the style of SOAP operation involved. The WSDL for the .NET server states that it is document/literal. To avoid this problem, I would recommend always using a WSDL description to define both clients and servers. Modifying the .NET server to be an RPC/encoded endpoint for easy interoperation is simple: Just add the [SoapRpcMethod]attribute to the method attribute:

[WebMethod] 
[SoapRpcMethod]
public int Add( int A, int B )
{
     return A + B;
}
Specific WSDL Issues

WSDL interoperability problems are still being discovered. Typically, they revolve around two issues: advanced namespace handling and schema processing. There are certainly other issues, but these are the most common.

There are also two major schema problems. The first problem is lack of support for the 2001 Recommendation of XML Schema. The other problem has to do with the XML Schema processors that WSDL engines use: Many of them don't understand all of the advanced features found in the XML Schema specifications, such as element substitution groups.

By advanced namespace handling, I mean the manner in which WSDL and XML Schema use namespaces, along with the targetNamespace attribute, to refer to some values. To illustrate, a WSDL document will have a specific targetNamespace and a prefix bound to that namespace:

<definitions 
     xmlns:tns="http://tempuri.org/"
     targetNamespace="http://tempuri.org/"
     xmlns="http://schemas.xmlsoap.org/wsdl/">

Now, there are several elements within WSDL that are given names, such as portType:

<portType name="Service1Soap"> 

And this portType element is referred to later with a QName that resolves to the targetNamespace:

<binding name="Service1Soap" type="tns:Service1Soap"> 

This seems simple enough, but several implementations have gotten this wrong at times. Instead of remembering to use the tns prefix, they have given the type a simple NCName. The result is that resolution of the QName won't work.

WS-I Profiles

The Web Services Interoperability organization (WS-I) is a new industry consortium that was formed to ease the burden of achieving interoperability. It is achieving this by creating "profiles" of Web services. These profiles describe a safe subset of SOAP, WSDL, and other specifications that enable developers to design a Web service with a much higher probability of success in terms of interoperability. WS-I is also building sample applications that demonstrate how to create a Web service with these profiles, and a test group is building test tools for verifying a service's adherence to the basic profile.