I'm doing some research into the creation of a web services addon for roo. I'm not committed to anything yet, but I'm probably going to work on some prototypes and may end up releasing an addon.
So I wanted to throw around some ideas with the community and see what people want/need.
Here is what I had in mind from a functional point of view:
I'm imagining a user that wants to allow access to their application through standards based web services. One simple and common thing to do would be to expose CRUD operations on the applications entities. This could be managed by a Spring Roo addon.
Upon installation of the addon, required dependencies would be added to the maven pom, and a servlet would be added to the web.xml to handle web service requests. The addon would then scan for entity classes, and generate web service endpoints for each entity (along with the crud operations). The endpoints would then be configured for use by the web service servlet.
As the user continues to develop their application, the web service endpoints would be kept in sync with the entities. Removing entities would remove endpoints, and adding entities would trigger creation and configuration of new endpoints.
The only required configuration I can think of would be for security, theoretically I think everything else could be driven by conventions.
Now from an implementation standpoint:
There are a multitude of Java web service stacks out there - I think the main ones are Axis2, Metro, and Spring Web Services.
Obviously Spring Web Services will need to be supported in Roo at some point, but I'm not sure if contract-first is the best fit for automatic crud interfaces. At the moment I'm leaning towards Metro, which requires very little configuration when given an endpoint, integrates well with Spring, and is the stack I have the most experience with. I'm open for suggestions here.
With the endpoints, it would be cool to implement the standard crud logic in aspects and leave the actual endpoint classes empty. This would allow users to go in and implement custom logic themselves inside the actual class. They could also override default crud methods this way.
I know I've rambled on for too long, but that is my vision. Probably a little ambitious...
What are your thoughts?
What you've described sounds to me as if it more closely matches a remoting layer than the major alternatives of a REST layer or SOAP/WS layer. We already have building a REST layer pretty well accommodated via the Spring MVC integration. As you noted, Spring Web Services favors a contract-first model as this provides benefits such as long-term maintenance of the API in a backwards-compatible manner. This is pretty different from a remoting layer, where the remote clients are expected to present serialized data and receive serialized data of the precise version of the remoted interface (yeah I know about Thrift - I'm speaking in general terms here ;-) ).
So to tackle a remoting layer you'd probably want to start by auto-generating a "remoting facade layer" to expose the persistence operations. I think this would be a great start as many modern remoting systems already (or can be made to easily) detect runtime-retention annotations and then expose the annotated methods and types over a particular remoting protocol at runtime (ie without needing actual development-time code generation). We could easily make that happen, for example, for Spring Framework's out-of-the-box remoting technologies like HttpInvoker. It would similarly act as a good starting point for remoting to 4th-generation web technologies like GWT and Flex.
I guess my key questions are what are your requirements and objectives in terms of simplicity/speed of development and long-term maintainability (ie client versioning compatibility)? This will largely influence whether you're better off with REST with XML, remoting (with assorted protocols and framewrks including those which automatically publish SOAP endpoints) or contract-first web services. Also, do you have the time and motivation to work on a Roo add-on for this (I'll be happy to offer advice and support, but I don't have enough time at present to code it myself)?
Hi Ben, thanks for the detailed reply.
Your right, a remoting layer does much better describe what I have in mind, "Web Services" probably wasn't the name for the thread or indeed to describe the addon.
Creating a remoting facade layer is an interesting suggestion - would it be aligned to the design principles Roo encourages? The static persistence methods added to entities are quite coarse already, what are your objections to endpoints calling these methods directly? (much like the web layer does)
Currently I'm leaning more and more to using the Metro stack to expose SOAP endpoints. Using Metro, I would just have to generate annotated endpoints, and the rest would be generated and compile time by the Metro maven plugin.
I do understand (and have experienced) how imperfect auto-generated SOAP services are, however, I think it is a fair compromise for the advantages this strategy offers. Even though it could be painful, there is still the possibility of interoperability with different platforms, while using something like Springs HttpInvoker completely rules this out.
Client versioning is a good point, and something I have not thought about. I may end up first creating an addon which does what I have already describe, and then focus on making it something that is easily maintainable. It is definitely something I need to think about. Thanks.
As for time and motivation, at the moment, the answer is "I think so". Like I said I'm still pretty early on in even the thought process so I'm not entirely sure how it will turn out. The bottom line is that contributing code to an open source project is something I have been wanting to do for a while, and Roo has inspired me with it's possibilities.
Thanks again for your interest.
My instinct would be to add a remoting layer so you avoid the potential complications of trying to annotate the static persistence methods that are provided within Roo entities. Certainly if your remoting framework supports exposing static methods directly, that's definitely easier and probably a reasonable starting point.
A remoting layer makes sense if you have more complex needs. For example, you could achieve better client versioning support by using DTOs. Given you have the remoting layer methods, and you build DTOs just for the clients, it's easier to isolate changes in the entity layer from what the client expects (and the remoting system exposes). Mapping between entities and DTOs also gives you a place to apply more elaborate copying logic, such as deciding at what point in the object graph you want to stop taking data, or possibly deciding whether a particular user has authorization to read a field (when entity to DTO copying) or write a field (when DTO to entity copying).
Personally my preferred technique for addressing remoting in 2009 is JSON-based REST. More advanced systems I've been involved with selectively copy fields from JSON documents to/from entities based on authorization and use-case specific rules. Exposing a JSON layer is also nice in that it means you haven't coupled your client to a particular backend technology (as you would if you used a platform-proprietary protocol like RMI). Favoring REST with XML (and similarly for SOAP) is you have an XML schema you can publish for the payload (or entire service in the case of SOAP), which may appeal if your remote clients are more likely to be running in fully-fledged programming language environments and can take advantage of the XML (or SOAP) definitions (eg on the JVM, Erlang, .Net, Python etc). If your remote clients are more likely to be browsers, they rarely have useful tools for consuming XML schemas anyway, plus they offer far better JSON performance than with XML. If the transmission payload size is important, you might find JSON or a binary protocol better than XML. However, if circular references are an important part of the domain, or being able to publish an actual specification, XML is probably a better choice. Don't forget the value of REST versus say web services is programmers increasingly understand the REST paradigm and publishing a REST layer will mean you lower the conceptual weight of third parties (or even new people on your internal team) understanding how to interact with your service. But SOAP is a good choice if you have large batches of documents to process, as you can use alternate transports and not be forced through the process of batching HTTP for REST. I would also take a good look at Thrift, which I consider an attractive binary protocol that tried to offer similar transport flexibility and therefore batch performance. Thrift seems well-suited to most applications, although notably not browser-to-backend communication (where you're almost always better off with JSON, although whether JSON over REST or JSON over COMET/IFRAME/SCRIPT/ActiveX etc is an entirely separate deliberation).
Like nearly everything in computing, it's just a game of trade-offs depending on your specific requirements. :-)
Thanks for those details. I know there are a lot of research involved there but still you managed to compile them all.