WS-DuckTyping
One of the most popular features of languages such as Smalltalk, ObjectiveC, and Ruby is Duck typing. To quote Wikipedia:
[…] duck typing is a form of dynamic typing in which a variable’s value itself implicitly determines what the variable can do. This implies that an object is interchangeable with any other object that implements the same interface, regardless of whether the objects have a related inheritance hierarchy.[…]
The term is a reference to the duck test — “If it walks like a duck and quacks like a duck, it must be a duck”.
So what does this have to do with Web services? Well, duck typing is a great way to create graceful and interoperable Web services. Web services are about exchanging information, and as long as the information walks like a duck…
Here are my three tips to implement WS-Duck Typing:
Don’t validate incoming messages!
Not only is XSD-based validation slow, it also requires strict schema conformation from the other party, thus creating a strictly typed service. Such a service breaks Postel’s Law: be conservative in what you do; be liberal in what you accept from others.
If you really want to do validation, do it on server-side outgoing messages only. After all, you should adhere to your own schema. Also, Schematron is the exception to the rule, since it not based on grammars, but on finding tree patterns in the parsed document. Which brings us to:
Use XPath!
XPath is an excellent way to extract information from an XML document. Code written with XML API like DOM, SAX, or StAX is typically quite fragile when it comes to element ordering, nesting, or unexpected elements. And XML marshalling isn’t much better: some of these API’s throw exceptions in these cases.
Not with XPath. When using XPath, you don’t care whether the <lastName> element is the first or the second child of <person>; the /person/lastname expression grabs it anyway. And if if you really don’t know where to find the last name, you can always resort to //lastname, which finds it anywhere in the document.
In the past, XPath has dismissed as being too slow. With modern XPath libraries which support XPath pre-compilation, this is less of an issue.
Don’t create stubs or skeletons!
This is perhaps the most controversial tip. If you create client-side stubs or server-side skeletons in a strongly-typed language like Java, you throw away any option of being liberal about the XML messages. Instead, you have create a strongly-typed API that is strongly-coupled to the contract, and that passes or expects parameters of a certain kind. If they are of any other kind, or if they are simply not there, your code will never be invoked. Even if you didn’t need the parameter in the first place.
If you treat Web services like XML messaging, rather than RPC, you could have handled the message gracefully: let’s see if I can find the first name under the person element, and if it’s not there, I’ll try and find in anywhere in the document. Still not there? Perhaps it’s an older message: I’ll just apply this stylesheet, and see if I can find the first name then. Et cetera, et cetera.
Hopefully, these tips will help you create flexible, interoperable Web services that gracefully handle XML messages.
Quack!