Arjen Poutsma on Spring Web Services
InfoQ's Stefan Tilkov had a chance to talk to Spring web services creator Arjen Poutsma about Web services in general and the Spring support in particular.
InfoQ: Can you tell us a little about yourself?
Arjen Poutsma (AP): I'm a Senior Consultant at Interface21. I've been doing Enterprise Application development for about 13 years now, first in in C++, then in Java, with a two-year period where I did some .NET development. I started to become interested in Web services about four years ago, and have advised some large corporations as to how to implement them.
For the last year-and-a-half I've been working on the Spring Web Services project, a product from the Spring portfolio focused on creating contract-first, document-driven Web services. Recently, we have released Milestone 3 of Spring Web Services, and we plan to release 1.0 in the second quarter of 2007.
InfoQ: What has been the main motivation for building Spring Web Services? Aren't there enough Web services frameworks for Java already?
AP:In my work as a consultant, I came across customers having major issues with their Web services. For instance, they wanted to maintain multiple versions of a service contract, or handle the incoming XML directly, without it being converted to an object first. At the time, existing SOAP stacks focused on making it easier to "SOAPify" existing Java classes, rather than do it the right way: start by writing a service contract, and write classes that can handle the incoming XML. While it was possible to do contract-first Web service design, it wasn't easy. Just as the entire Spring portfolio does, Spring Web Services makes the right way easier, and shows people how to fit Web services in their existing architecture.
InfoQ: Many people would argue that converting XML to objects and back is exactly the functionality they're looking for in a Web services stack. You seem to disagree - can you elaborate?
AP:I think developers should have a choice to handle the incoming XML any way they want, XML marshalling being one (convenient) way.
However, there are several issues with XML marshalling. One of them is that some marshalling engines are quite fragile, i.e. they blow up when they come across XML they don't know about, which doesn't really fit well with Postel's Law (be conservative in what you send, be liberal in what you receive).
Another thing is that there is quite a structural difference between an object-oriented language such as Java or C#, and a tree-based language such as XML. Take object graphs, for example. Let's say that I have a Person class which has a spouse property, so that the spouse of a spouse point to the same object. There is no standard way to represent such a relationship in XML; you can only resort to a custom mechanism. Another issue is that of data types: in Java we have a java.util.Map, and basically two implementations of it (HashMap and TreeMap). XML Schema (XSD) does not have a datatype for a dictionary structure, so what happens when I marshal a HashMap to XML?
Hopefully, I will get some sort of XML out of it, but when I unmarshal it again, I will probably not end up with the same HashMap I started out with.
So there is no such thing as transparent marshalling, in the same way as there is no transparent object persistence. You will have to instruct the marshalling engine how to convert your objects to XML, much in the same way as you instruct an Object/Relational Mapper to convert between SQL and objects. That's why I prefer to call it Object/XML Mapping instead of marshalling, because it makes clear that there is also Object/XML impedance mismatch to take care of.
InfoQ: What's your opinion about JAX-RPC/JAX-WS?
AP:When JAX-RPC was released, people thought about Web services as just another way to do Remote Procedure Calls. The name of the specification clearly suggests this. During the years, we have figured out that a behavior-driven, RPC-like way of doing Web services is not the best way to go forward. It results in a tighter coupling between client and server, and also completely ignores things like latency, failure, lack of a shared memory access, etc. Instead, a data-driven, message-like methodology is a better fit.
JAX-WS is an improvement over JAX-RPC. The thing I particularly like is the Provider API, which offers an message-focussed way of handling incoming SOAP requests. What I don't like is fact that the rest of the specification is still pretty much focused on RPC, and that there is a strong dependance on Java 5 features, even when there are perfectly fine Java 1.4 alternatives. It seems like every JSR that comes out these days has to define a couple of annotations. There are still a lot of Java 1.4 or even 1.3 users out there, and they can't use generics, enums, and annotations, all three of which are required when you use the Provider API mentioned above.
InfoQ: What makes Spring Web Services unique, why would I use it instead of Axis, XFire or ActiveSOAP?
AP:Spring Web Services has a couple of unique features. Firstly, it's completely focussed on contract-first Web service design. This basically means that you have to write your own XSD schema that defines the XML messages. You can refer to that schema in a WSDL (though Spring Web Services can also generate the WSDL from the XSD), and possibly use it for validation purposes. The interesting thing is that a lot of the interoperability issues that people have with Web services disappear when they use a contract-first development style. That is why contract-first is generally considered to be a best practice. You are basically designing a XML API: the fact that you implement that API using Java is just an implementation detail which no client should care about.
Secondly, Spring Web Services provides a loose coupling between contract and implementation: there is no wsdl2java tool which directly ties the contract to a class; instead, you implement endpoints which handle the incoming XML in any way you want to (DOM, SAX, StAX, or even XML marshalling techniques such as JAXB, Castor, JIBX, or XMLBeans). The way you map incoming request to the endpoints is completely up to you: by default, we supply mappings that are based on message content, or the SOAPAction header. The main idea is that you're not handling method calls, but rather XML messages.
Finally, there are some features which you can expect from a Spring project:
- the WS-Security implementation integrates with Acegi Security,
- the JMS support uses Spring 2's Message Driven POJOs,
- the main client-side class (WebServiceTemplate) offers an API similar to JdbcTemplate,
- the XML marshalling support is completely independent of Web services (so that it can be used in other settings),
- it works on JDK 1.4 and above (though there are also Java 5- specific features).
InfoQ: So by default, my application gets passed the XML from the message? In what form - as a DOM tree, a stream, a reader or something else?
AP:The application gets passed an XML input abstraction to read from, and a output abstraction to write to (javax.xml.transform.Source and javax.xml.transform.Result respectively). This way your code isn't tied to any particular XML handling API. The actual implementation of this mechanism depends on the message factory you choose to use. We offer two for SOAP: the default is based on SAAJ (javax.xml.soap, part of J2EE 1.4), which uses DOM underneath. For larger messages we support AXIOM from Axis2, which uses a StAX stream.
InfoQ: How does Spring Web Services handle WS-* standards - do you support any of them out of the box?
AP:Spring Web Services supports SOAP 1.1 and 1.2, WS-Security, and support for generating a 1.1 WSDL out of a XSD schema. WS-Addressing is planned in the post 1.0 timeframe. Basically, I tend to wait with implementing a standard until there is sufficient user request for it. So far, people seem pretty happy with what we have.
InfoQ: What is your general opinion on the WS-* landscape?
AP:Well, there are parts I like and parts I don't like. I like SOAP, I think it's a nice way to send XML messages across transports. I don't like WSDL that much, because it offers an almost object-oriented model of a Web service with operations, interfaces, etc., which doesn't fit well with SOAP. SOAP doesn't have operations, it is just an XML message. In that respect, I like SSDL (the SOAP Service Description Language) more.
I like the concept of WS-Addressing: to put addressing information in the SOAP Header, but I don't like the fact that there are five different, and incompatible versions of it in use. Basically, if someone tells you that their service supports WS-Addressing, you need to ask: "Do you support the March 2004 version, the August 2004 version, or any other version?"
And finally I think WS-Security is quite useful. It doesn't try to reinvent the wheel, but uses XML-DSig and XML-Enc where it made sense.
InfoQ: What's your take on REST, and do you think Spring Web Services will support it some day?
AP:I like REST, I like the way it solves a lot of problems we face in the WS-* space by basing itself on HTTP, a proven technology. That said, I think that REST is just as, or even more restrictive than SOAP is. When writing a REST service, you have to have a clear idea about what your resources are, which data formats you support for them (REST is not just about XML!), which HTTP methods you support on them, and what they mean. All of this has to be clearly documented as well; the HTTP specification isn't enough for this purpose.
A lot of people say they do REST, but what actually do is something Don Box has named POX (Plain Old XML). POX is an XML messaging protocol, where you simply send XML message, without the SOAP envelope wrapped around it. Spring Web Services already supports this.
Regarding "true" REST support, I think we will support it in the future, but not in the 1.0 version of Spring Web Services. It is very different from SOAP and POX, for instance, there is no XML message coming in at all time. We don't want to support REST by creating a XML message from an HTTP request, shooting that into the pipeline where three milliseconds later it gets parsed again: that's simply too expensive. Instead, we will base the REST support on Spring-MVC, Spring's Web framework.
InfoQ: Thank you for your time!The Spring Web Services product can be downloaded from the Spring web site; Arjen also maintains a blog on Web services.
One more question
Re: One more question
One more question for Arjen: When will Spring-WS have some decent documentation?
I am biased, but I would say that the 37 pages of existing documentation are quite decent: it has a tutorial on how to create a good XSD schema and WSDL, it describes the Object/XML Mapping abstraction, and how to implement WS-Security in your web service.
I'll admit that there are two very important parts missing in the docs: the new client-side support, and the server-side implementation of the service. You can expect those chapters in the 1.0 release, due Q2 this year.
In the mean time, there are two sample applications which help you on your way. One is a simple echo sample, the other a complete airline application with a business layer, and DAOs using Hibernate.
Re: One more question
Re: One more question
Re: One more question
BUT, the documentation of the project isn't that good at all. I mean, it has some good material about contract-first ws, and some partial material about sort of 'advanced' features like mashalling and security, but has close to nothing about writing basic services using Spring WS. Not even a 'echo service' tutorial. I mean, saying 'it is similar to Spring MVC' doesn't count as documentation :)
You're right, I have removed these "partially done" pages, because they're not much help. I will return them when finished, before 1.0.
Now that is good news! Keep the good work, and good luck.
Spring-WS and JMS
You mentioned JMS support in Spring-WS, but I understand that the SOAP/JMS binding is not an industry standard yet. I need to run SOAP messages over a queue rather than HTTP. Is there a way to use Spring-WS with JMS in a way that is future-proof or "standards-ready"?
Re: Spring-WS and JMS
The good news, however, is that the Spring-WS JMS support currently available in the sandbox uses a BytesMessage, just as the proposed standard does, so at least we're partially there :). The bad news is that most other stacks I've looked at use a TextMessage, so both the standard and Spring-WS are incompatible with it. The code will be moved out of the sandbox when we are compliant with the standard, or earlier when the spec takes too long to finalize.