Last week was enlightening. I'm working on a project that is providing a set of services for internal consumption. The interface is actually pretty simple. We have four entities, CRUD on 3 of the entities and two operations on the fourth. Conceptually the interface can be described in five minutes. It can be expressed rigorously in any OOP language in about an hour. (The service implementation is considerably more complex, but the interface is relatively straightforward).
We opted to implement the services using SOAP. Enter WSDL. The conceptual interface was translated into WSDL which took more than a day. Once the WSDL was finally validating, we were able to generate code in Axis. Then we moved on to C# and GSOAP. Neither of them would work without further modifications to the WSDL. Another day lost on compatibility. Once the servers were deployed, we ran into issues where GSOAP generated code that compiled but didn't work. There were name space challenges. What took the engineers an hour to express in Java was taking days to express in WSDL. And I want to reiterate that this is a relatively simple interface.
Why didn't we just write the interface in Java and use java2wsdl to generate the WSDL then? Well, one reason is that the services have to be split for security reasons which leads to different ports in WSDL terms. Auto-generated WSDL would not have captured the common types with the appropriate file structures. And philosophically, if WSDL is my implementation neutral interface definition language, then it seems I should be writing it, not generating it from a specific implementation of the interface. Finally, from a stylistic point of view, I'm still waiting on the code generation process that makes files that are easy to read and understand by humans.
As long as we're on the subject of human readability, WSDL fails miserably at this quality. It is similar to reading XML schemas, only harder. Some of you may decide at this point that I'm not much of a software engineer if I find XSD and WSDL difficult to read, and so be it. But I can read a DTD and RELAX NG specifications with ease. I would expect any specification that purports to be a mechanism to allow developers to communicate interface semantics to be clearly understood by developers and not force them to rely upon tools to translate into languages they know.
"So what", some will argue. WSDL is about allowing tools to generate interfaces and is not intended for human consumption anyway. I'll argue that it lacks sufficient constraints to allow that to work well either. What does a java.util.Date map into in C++? What does an unsigned long long map into in Java? The entire XSD type space is available in WSDL which leaves the door open for developers to create unusable interfaces, especially if these interfaces were code generated from an implementation interface.
Yes, I am a heretic. I dare to boldly state that WSDL is an impediment to building services. I'm sure the intentions were good and honorable but the result misses the mark. There is a next generation WSDL in the works but it doesn't appear the primary goal is to improve either of these issues. If anything, I am concerned that 2.0 will get further from human readability than 1.1.
What is the answer? I don't think the answer is to abandon the concept of specifying interfaces. Quite the contrary, I am a big fan of having a way to express the semantics of interfaces in a way that is better defined than natural languages. The specification should support more than just SOAP interactions though. Ideally, I would like an IDL that could accomplish the following goals.
- Provide syntax and semantics that are more readily understood by developers. I think XML is a reasonable tool for such an IDL but the focus should be on readability. Think RELAX NG vs XSD and you have the idea.
- Support a variety of interactions. SOAP has WSDL although there is no reason a new IDL couldn't easily express SOAP interactions. It should also be possible to describe REST interactions with this IDL.
- Provide more control over the transport binding. The primary transport in use today is HTTP. My IDL would allow me to leverage all HTTP operations, specify headers that are meaningful as well as the content-type of the body. This would allow operations that supported any of the available media types to be expressed. Other transports could be supported but in each case, the binding semantics need to leverage the full richness of the transport.
- Don't preclude code generation. There is nothing wrong with code generation, I just feel that it should go from the IDL to the implementation and not vice versa. Partial code generation should also be supported, say for example just type handling.
I have spent the past few weeks thinking about how such an IDL might look. I've also struggled with questions of usefulness and adoption. I'm certain that having nothing is the wrong answer and my experience to date with WSDL tells me it is a suboptimal solution.
What do you think? Leave your comments or trackbacks and let me know.