WSDL Tales From The Trenches, Part 2
In a previous article ("WSDL Tales From the Trenches, Part 1"), I painted a big picture of web services design. As I said, Web Services Description Language (WSDL) only defines the syntax of how a web service may be invoked; it says nothing about its semantics. I will observe this distinction in what I say in this article about WSDL.
The version of WSDL being most widely used now, 1.1, is published as a W3C Note. It is not an official standard. WSDL 1.1 offers a lot of latitude for invoking web services. Tool support tends to be patchy. WSDL gets a lot of bad press because it got the trade-off wrong between expressivity and flexibility on the one hand and verbosity and complexity on the other. Before we proceed, I will come clean and tell you that I am at a loss to tell you how to write truly clear, crisp WSDL.
Tools
Before getting into details, let's consider the possible tool support you may be able to rely on. First, it helps to use an XML-aware editor when you write WSDL, preferably one with the capability to validate the WSDL document. When retrofitting WSDL to existing web services, I find it very useful to be able to generate, send, and receive messages from the editor; XML Spy from Altova does this for web services with SOAP over HTTP bindings. This makes it practical to develop, test, and debug WSDL interactively. Unfortunately, XML Spy does not provide this capability for other bindings. A useful feature that seems to be missing in today's tools is the ability to validate a server's response against a web service description (hereafter, "WSD").
Modular web service descriptions
Using the import keyword, you can separate a WSD into
modular documents. An example in the W3C Note uses three documents, which
contain, respectively, data type definitions, abstract definitions, and
specific service bindings. The specific or concrete service definitions
depend on the abstract service definitions, which in turn depend on the
data type definitions.
Apart from improving readability, this technique also improves opportunities for certain types of extension and reuse: the same data type definitions can be used across many abstract services, and the same abstract services can be offered through many different bindings, at many addresses.
Initially, a set of web services may be represented as a set of three documents. As services grow, however, this may evolve into a tree of documents with the data type definitions at its root, branching into several abstract services documents, and further fanning out to concrete services.
portTypes are collections of semantically related
operations, much as an interface in a programming language. A
binding does not have to cover all operations of
a given portType. For example, the respective
operations may use different transfer protocols. Since a
service is a set of ports and a
port refers to a single binding, it is possible
to specify services that do not offer all the operations
defined in a portType. However, the presence of such
services is indicative of badly factored
portTypes.
A single service may be composed of many interfaces, each representing a different aspect of the service. For example, a service may have a port for its business logic and another port for accessing its management features.
Namespaces
WSDs, once agreed upon, should be frozen. WSDL 1.1 makes the use of target namespaces optional. It is convenient, however, to assign a namespace to identify services and their versions unambiguously, as has become the common practice with standards specifications. The downside is that WSDL 1.1 is not very clear about what is meant by the target namespace. In other words, what precisely is being put into it? I suspect that the same rules were meant to apply as with W3C XML Schema.
Here's a quick recap of the rules in W3C XML Schema: what is put into
the target namespace is governed by the form attribute on the
element and attribute elements. In the absence
of such attribute, the defaults set at the level of the root schema
element through the elementFormDefault and
attributeFormDefault attributes come into play. In the
absence of an explicit default, the implicit default applies: only
globally defined elements go into the namespace.
What are the repercussions of these Schema rules on WSDL? First, WSDL
does not deal with elements and
attribute. Second, the top level elements in WSDL are
messages, portTypes, bindings, and
services, which are the entities that will be put into the
target namespace. types is obviously not relevant
here. Third, while in theory Schema's form attribute could be
used with any of the elements defined in WSDL, this is not common
practice. Fourth, similarly, Schema's elementFormDefault and
attributeFormDefault attributes could be used on the
definitions element, but I have not seen it done.
Thus, we can say that all messages,
portTypes, bindings and services go
into the target namespace, and their children do not.
Is this rule useful? Does it matter? It does when messages are
encoded in such a way that, except for this rule, the WSD
namespace could "leak" into messages. Indeed, it took me some time to
figure out that the namespaces I was seeing in encoded SOAP messages were
not due to the WSD namespace because of the common, but confusing
practice of using the same namespace as input for SOAP encoding. A
corollary of our namespace rule is that a message's elements and
attributes are not in the WSD's namespace, unless they are put
there by the SOAP encoding namespace.
If a WSD is modularized in the way I suggested before, a namespace
should be assigned to each document. WSDs should not import
definitions with the same namespace. The WSDL specification does not
state this rule explicitly, but again, I suspect Schema's
import was the inspiration for WSDL's element of the same
name and that the same rules were intended. Schema does not allow an
importing and imported schema to share a namespace. This is a very useful
rule in my view since a namespace is difficult to reason about if you
cannot rely on the fact that the definition is complete.
Pages: 1, 2 |