Monthly Archives: November 2006

Schema Compliance is the Key to Interoperability

Good Web services interoperability
is an absolute must for a successful SOA implementation, but why
interoperability has been so difficult to achieve?

I think that inability to comply with a published Web services contract
expressed via its WSDL/Schema could be one of the leading causes of
interoperability problems (I use the term “interoperability” pretty broadly here).

For example:

  • Many “wrapper” service implementations use positional parameter binding, as I
    described in
    my previous post
    . This allows a service provider to accept messages
    will never validate against the schema. Then, certain changes in
    implementation (a different binding mechanism, switching from “wrapper” to “non-wrapper”),
    could all of a sudden start causing issues for clients that have never had any
    problems before.

  • Some Web services clients always generate messages using qualified local
    elements thus ignoring what is in the schema (the default is actually “unqualified”).
    This may work for some binding frameworks but not for others.

  • Different JAX-RPC implementation handle “xsd:anyType” differently. Some generate “Object”
    bindings; some use SOAPElement and some actually allow using DOM’s “Document”
    or “Element” (as an extension to JAX-RPC).
    This would be Ok if serialization/de-serialization
    process did not change depending on the binding,
    but that unfortunately is not always the case.

  • Handling of “nillable” (xsi:nil) and required elements. If an element is
    declared as required but nillable, it must be provided as part of a message.
    Instead, some Web service clients omit an element if it is “null” in Java.

My biggest pet peeve is that most JAX-RPC implementations today don’t even
support schema validation out of the box (hopefully this will change in JAX-WS).
I understand that full validation against a schema could be expensive, but can
we at least handle required parameters/fields as they defined in the schema?
Types mismatch will certainly cause an error, why not a missing mandatory field?

Note that I’m not talking about WS-I profiles, .NET/Java interop, and
differences in WS-* implementations. I’ve seen all of the above problems while working
with different Web services implementations in Java (mostly JAX-RPC).

And it is not just about interoperability – reliance on subtle conventions as
opposed to a published contract makes architectures more fragile and more
tightly coupled.

So my advice is simple – write a handler (at lest for development/test
environments) and enable schema validation on the server and, under some
circumstances (i.e., you don’t control the service), on the client. This will
save you from many interoperability problems, guaranteed.

“Wrapper”/”Non-wrapper” Web Service Styles – Things You Need to Know

“Wrapper”/”non-wrapper” Web services styles are mandated by JAX-RPC and JAX-WS
specifications
and are explained in details in documentation or in other sources, for
example in
this article
. However, from my experience, there is still a lot of
confusion among developers about differences between these two styles and also
how a particular style affects design and implementation of a Web service.

First of all, we need to understand that “wrapper”/”non-wrapper” style is a
characteristic of a Web services implementation framework (such as JAX-WS), as
opposed to a style defined in WSDL. In fact “wrapper”/”non-wrapper”
can only be used in conjunction with the document/literal style defined in WSDL.
“wrapper”/”non-wrapper” setting defines how Web service request/reply messages
are interpreted by a Web service provider/consumer. Quite simply, “wrapper”
style tells the Web service provider that the root element of the message (also
called “wrapper element”) represents the name of the operation and it is not
part of the payload. This also means that children of the root element must map
directly to parameters of the operation’s signature. The “non-wrapper” style (also
sometimes called “bare”), does not make this assumption; in this case the entire
message will be passed to the service operation. The reply message is handled in
a similar way.

“Wrapper” style can be used for the following method:


public String produceFullName( 
        // note we have to provide names in annotations
        // to comply with the schema.
        // otherwise generic "in0", "in1" names are used.
        @WebParam(name = "firstName")String firstName, 
        @WebParam(name = "lastName") String lastName );

The request SOAP messages for this method will look like this:


<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <produceFullName xmlns="http://personservice">
      <firstName>John</firstName>
      <lastName>Doe</lastName>
    </produceFullName>
  </soap:Body>
</soap:Envelope>

However, suppose we implemented the same function differently:


public String produceFullName(
        @WebParam(name = "person", 
                targetNamespace="http://person") 
        Person person );

This method can be used with “non-wrapper” style resulting in the following
request message:


<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <ns2:personExt xmlns:ns2="http://person">
      <firstName>John</firstName>
      <lastName>Doe</lastName>
    </ns2:personExt>
  </soap:Body>
</soap:Envelope>

In JAX-WS, “SOAPBinding” annotation can be used to specify the style, e.g.,
@SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE).
Note that “wrapper” is the default. In JAX-RPC the “wrapper” style is
specified in the Web service mapping xml file by adding “wrapped-element”
element to the service endpoint mapping.

If you generate your Java artifacts from WSDL file, the “wsdl2java” tool
will automatically assume “wrapper” if operation name matches the wrapper
element name and if some other requirements are met (some “wsdl2java”
implementations also allow to control “wrapper”/”non-wrapper” using a command-line option).

So once again, “wrapper”/”non-wrapper” is a data binding style used in the
context of a particular Web service provider/consumer. It is not part of the
contract of a Web service, since it is not mentioned anywhere in the WSDL file.
In other words, if you are a Web service provider, your consumers don’t have to
know or care whether your implementation style is “wrapper” or “non-wrapper”.
They may very well choose the “non-wrapper” style for their client’s
implementation and this client should interoperate with your “wrapper” service
without a hitch (at least in theory).

In fact, the “wrapper” style is supported widely but not universally.
From what I understand, the support for the “wrapper”
style first appeared in .NET and later on Java-based Web services frameworks
began supporting it as well (in Axis and others). I think it is also supported
by Perl SOAP library. However, this style may not be supported by other languages,
for example, I believe that PHP 5 SOAP engine does not have a notion of the “wrapper”
style.

“Wrapper” style is really an RPC-style binding over “document/literal” WSDL
style. The basic premise of the “wrapper” style is that our service is a remote
method that takes some parameters (as opposed to pure message-based paradigm of
a “non-wrapper” Web service, where method name is not explicitly provided in the message).
So how “wrapper” with “document/literal is better
than “rpc/literal” WSDL style? Here are some of its advantages:

  • “Wrapper” service can only have one message part in WSDL, which guarantees that
    the message (consisting of the method element that contains parameters) will be
    represented by one XML document with a single schema.

  • RPC style message definitions in WSDL have to use schema types, whereas with the
    document style we can refer directly to element names. This makes XML message
    representation more “precise”, it is also easier to validate.

  • RPC/literal, while WS-I compliant, fell out of favor and being
    frowned upon, not
    in small part due to poor Microsoft support.

“Wrapper” style has one interesting drawback, which may not be immediately
obvious. Most Web services engines (at least the ones that I had a chance to
work with) use positional parameter binding with “wrapper” style. This means
that if a service signature changed (e.g., a new parameter was added), clients
will have to change as well. In other words, with “wrapper” style, all
parameters have to be present in the XML message (although they can be defined
as null using “xsd:nil” attribute). This is despite the fact that the element
corresponding to the parameter can be defined as optional in the schema. “non-wrapper”
style does not have this problem; adding a new optional element does not
affect clients, since binding is always name-based. This creates somewhat
tighter coupling between “wrapper” style consumers and providers. This may also
violate the contract of the Web service defined by its schema. To get around
the last problem, you may want to define all child elements of the wrapper root
element as required (minOccurs=1); optional elements must be made nillable. For
some reason JAX-WS spec does not explicitly state this.

JAX-WS, however, does impose some additional restrictions on the “wrapper” style,
the most important one being that the wrapper element’s content type must
be “sequence”. This makes sense, since we’re trying to model a method’s
signature, which is always represented as an ordered list of arguments (at least
in Java/C#).

As far as the “non-wrapper” style goes, probably the most obscure thing about it
deals with how a SOAP engine decides which operation to invoke based on the
message type (assuming a Web service has multiple operations), since operation
name is not explicitly provided by the message (unless “SOAPAction” header is
used, however, this header is HTTP-only and also optional in JAX-WS). With “non-wrapper”,
each operation must accept a message that corresponds to a unique XML element
name. Note that it is not enough to define different WSDL messages using “wsdl:message”
element, each message must be represented by a different element in the schema.
Web service engines use unique element names to determine Java method names (that
correspond to WSDL operations). This means that with “non-wrapper” you can’t
have different operation names processing the same message, e.g., process(Customer)
and processDifferently(Customer) can only be implemented by creating
different customer types.

So we have an interesting dilemma – “wrapper” does not support overloaded methods (in
fact, I don’t think WS-I allows them either), whereas “non-wrapper” does not support
methods with the same signature (at least under certain conditions).

So how should we decide when to use the “wrapper” style? My approach is always
the following:

  • Design good “tight” schemas for your request and reply messages. Do not rely on Java-to-WSDL/Schema
    generation. Hopefully, you have good requirements as the basis for your design.

  • You can now see if the request schema matches the Web service operation’s
    signature. If that is the case, “wrapper” might be your choice. Consider pros
    and cons of each style described above. Basically, “wrapper” provides more “natural”
    RPC implementation, whereas “non-wrapper” gives more control and somewhat
    looser coupling (from a client’s standpoint). If you decide to go with the “wrapper”,
    do not assume that all of your clients will be using the “wrapper” (unless you
    know for sure that this will be the case). So make sure that your WSDL can be
    easily consumed by both “wrapper” and “non-wrapper” clients. For example, an
    element with empty sequence maps to “void” return type if the “wrapper” style is
    used; however, “wsdl2java” (or a similar tool used by other languages) will
    generate an empty class as the return type for “non-wrapper”. This last option
    may not be very intuitive or desirable for your clients.

  • When publishing your service, provide examples of its client implementation. You
    may not be able to address all the different languages and platforms; however
    covering the most widely used ones (most often, Java in C# in an enterprise environment) is a
    good idea. This will help your clients consume your Web service and also clarify
    the “wrapper” versus “non-wrapper” question.