
WSDL 2: Just Say No
by Rich Salz
November 17, 2004
We're happy to welcome Rich Salz back to his XML.com
column after a long absence. Rich was in a very serious accident, and we're
all lucky to have him back. -- Editor.
I recently read the Last Call drafts from the Web Services Description Working
Group of the W3C. I had no choice; I was on a cross-country
flight, my laptop batteries were dead, and the in-flight movie was
execrable.
The WG has actually produced three documents:
- The WSDL core
language;
- The set of pre-defined extensions
that covers things like common message and
fault exchange patterns;
- A set of bindings
that describes the mapping to SOAP, HTTP, and so on.
To put it simply, these specifications are astoundingly bad. The
comment period ended October 4, although looking at the comment
list archive shows that comments were still being received, and
processed, as recently as last week. According to W3C procedure, at
this point the Director can send the documents back to the group,
or he can allow them to move forward and ask for implementation
information as the next step in becoming an official W3C
Recommendation.
It is my feverent hope that not only will Tim Berners-Lee send
the documents back to the working group, but that he'll attend
their next face-to-face meeting and spank everyone involved. WSDL
2.0 is the worst example of architecture
astronautics I have ever seen. While these documents might be useful
to someone developing a WSDL tool, they are practically useless for a web
services developer who wants to use WSDL to define their interface.
Let me give three examples of what is wrong with WSDL 2.0.
No Standard WSDL File
The WSDL 2.0 document never defines what a WSDL file looks like.
At first, this looks like an oversight. For example, the "XML
representation" of a fault component is written like this:
<fault>
name="xs:NCName" element="xs:Qname"?>
<documentation />?
[ <feature /> | <property /> ] *
</fault>
First of all, the description is very misleading; it's hard
to see how this admixture of regular expressions and XML element syntax can
be called an "XML representation." The text that describes the syntax (in
section 1.2), in fact, calls it pseudo-schema and labels it non-normative,
meaning that it's not an official part of the specification. The description
of this pseudo-schema is very informal. It ends with the following
sentence: "Attributes are conventionally assigned a value which
corresponds to their type, as defined in the normative
schema."
This sentence has two problems. The first is that the phrase
"conventionally assigned" is far too informal for use in such a
formal specification. For example, the element attribute of a
message reference is defined as follows:
element="union of xs:QName, xs:Token"?
In other words, it's just psuedo-code: It can't be processed by a
machine, let alone any standard XML tools. This means it can't be
syntax-checked, and there's no way to build up any test cases to
see if the definition is actually correct and if it does what the
specification authors intended. (For example, the fault shown above
leaves out extension points.) All of these problems could have been
avoided by using the official schema language of the W3C:
<xs:attribute name="element" minOccurs="0">
<xs:union memberTypes="xs:Qname xs:Token"/>
</xs:attribute>
But there is an even bigger problem with the sentence quoted
above: there is no normative schema.
At this point, you turn to the conformance
section of the specification and see the following sentence:
Note that the WSDL language is defined in terms of the
component model defined by this specification. As such, it is
explicitly NOT a conformance requirement to be able to process
documents encoded in a particular version of XML, in particular XML
1.1
Think about the implications of this. XML web services are all
about interoperability. (The Web Services Activity
Statement, of which the WSDL Working Group is a part, says this
is fundamental: "Web services provide a standard means of
interoperating between different software applications, running on
a variety of platforms and/or frameworks.") WSDL is the way these
services are supposed to be defined. Yet the WSDL language itself
is defined in terms of a local data model. We can't even
talk about "comparing two WSDL files" since the 2.0
specifications don't define such a thing.
The WSDL specification deliberately refused to define an
interopable way of exchanging WSDL definitions across multiple
systems. The following, if it results in a proper Infoset, could be
a compliant WSDL 2.0 file:
#include "wsdl.h"
extern void hello_world(const char* text);
That's right, as of WSDL 2.0,
WSDL files are no longer portable. This cannot be a step
forward.
Yet Another Data Model
WSDL 2.0 introduces yet another XML data model, the WSDL
component. By now, I've lost count of how many data models there
are, but I know we have XPath 1.0, XQuery, Infoset (both pre- and
post-schema validation), and almost every RPC vendor has an
XML-datatype model of its own.
In WSDL 2.0, a component is a typed set of properties. Although
not defined in the specification, a property is a collection of
related data. For example, an operation component will have the
following properties:
- name--the name of the operation
- target namespace--from the enclosing
definition
element
- fault references--from the
infault and
outfault child elements
One thing to note is that some information comes from "up" the
tree, such as the target namespace, and some information comes from
"down" the tree, such as fault information. Information rarely
percolates up the tree; compare with the concept of in-scope
namespaces, for example. Unfortunately, it can get even worse.
Since a WSDL definition can import other WSDL definitions, a
component's properties can also include "up and over" data from
data at the same level in the tree.
Web services developers will need to deal with this issue if they ever need to
see whether two components are compatible. They cannot just start at the
comparable elements (okay, tree nodes) and walk through the tree. They will
have to keep the memory model in their heads as they walk through the two
definitions. (I keep wanting to write, "as they flip through the two files,"
but I'm trying to stick with what the specifications
define.)
As a minor complaint, the specification uses curly brackets to
delimit property names, as in {target namespace}. The
Infoset established the convention of square brackets, as in
[children]. The combination is typographically
confusing, as when you read that "the {features} property comes
from the feature element information items in
the [children] element information items, if any."
Web services developers will have to understand the component
model because of the decisions WSDL 2.0 made about multi-faceted
servers. As I'll explain in the next section, component equality
becomes very important now.
COM Comes Back
WSDL 2.0 renamed portType to
interface, which was sensible. They also defined an
inheritance model, which turns out to be less so.
In WSDL 1.0, a service could implement multiple ports.
This fits with the conventional model for implementing IETF/Internet
servers: each TCP port defines its own language (SMTP, NNTP, etc.),
and a single executable can implement multiple protocols, by using
the port number to de-multiplex (or dispatch) to the appropriate handlers.
XML doesn't have this concept of distinct port numbers. The closest analogue would
be to declare that the (namespace, localname) tuple of every
operation be unique, and this is what the WG decided to do. In other
words, operating overloading has been removed, unless the WSDL definition
defines an extension point to otherwise disambiguate between operations. I
don't have a problem with this, but some others, including two of the
specification editors, feel it's limiting and have
raised a formal objection to this decision.
I don't think it's a good sign when WG editors raise objections to a
specification in Last Call state.
Since a service can only implement one interface, how does WSDL 2.0 provide
extensibility and an acceptable programming model? They did it by adding
information inheritance. At first glance, it looks like Java inheritance,
and the specification talks about "extending an interface." Looking beneath
the surface, however, it's really just "extending the vtable," just like COM.
More from Rich Salz
SOA Made Real
SOA Made Simple
The xml:id Conundrum
Freeze the Core
XKMS Messages in Detail
In addition, WSDL 2.0 really allows for multiple inheritance; you can
define an interface D that extends C and
B, when both of them in turn extend the base interface
A. In order to make sure that the two intermediate interfaces
don't conflict--for example, that they don't define two different
operations with the same Schema element--the WSDL specification defines
sets of rules for determining if two components are equivalent. As you should
expect, equivalence basically comes down to checking for property
equality. This means, as a web services developer, if you are
implementing and extending someone else's service definition, you will
spend time going up, down, and over through the two trees, trying to find
out if there are any conflicts and, if so, where they are.
The alternative is to just trust and hope that the WSDL 2.0 tools--the ones you use and the ones all your clients use--get it right. And in
a bit of a reality check, not even the specification is that naive. In fact,
in several places it suggest that it is "good practice" to ensure that the
names of all items within a component are unique. This will not help re-use
and decentralized architecture, as it requires global coordination of names
within a namespace. Why not just use different namespaces?
They can't because of the one interface per service decision.
Stop Signs
I could go on and on, but I won't. I've tried to show why I think
that WSDL 2.0 is fundamentally flawed and should be sent back to the WG.
Please, Tim, reject these
Last Call documents.