Thursday, October 18, 2007

RESTing happily in Jersey

I've been working with Jersey over the last couple of months and I like what I'm seeing so far. Jersey is a REST/Web-based services framework for Java, based on the draft JSR 311 standard, nicknamed JAX-RS.

I've compared it to the other alternatives on the Java side for HTTP-based services, in particular Apache CXF, and here are the main highlights for me:
  • It's a lightweight framework that doesn't invade parts of your application where it doesn't belong. That is, it's used only in the external interface layer of classes called directly from the servlet. I really don't like frameworks that invade parts of your application where they don't belong, and I tend to stay away from these. Jersey however is well behaved and stays within its boundaries.

  • ConsumeMime and ProduceMime method annotations that also support routing of requests in addition to the URITemplates. This makes you think more about using proper media types rather than just making all your return types application/xml.

  • Hooks for Atom representation of your resources, using libraries such as ROME. Although some of my esteemed colleagues at ThoughtWorks disagree with me, I think ATOM is extremely useful when developing RESTful services, especially with its support of custom content types. No more custom collection types, and there's already a protocol for manipulating your collections.

  • WADL support, including automated generation of a WADL document describing your resources. I'm not convinced that WADL is a good idea as it seems to lead to tighter coupling of clients to resources. It also violates the REST principle of hypermedia as the engine of application state. However, it can be very useful when your architect demands an interface document for your service ;-)

  • Serialisation of JAXB objects out of the box. In other words, the classes exposing the external interface can return JAXB objects and Jersey turns them into XML or JSON (BadgerFish convention) on the wire. Yes, I know, CXF has this too.

  • It was designed as a HTTP/REST library from the beginning. This is really the biggest reason for me. The framework helps you make your service more RESTful—you don't feel like you're wrestling with the framework to make it do what you want. CXF is certainly my SOAP library of choice on the Java side (at the moment anyway) and the developers have done a very good job of adding support for Web-based services both within the confines of JAX-WS and using a non-standard API. However, the RPC-orientation of JAX-WS (which originates from WSDL) inevitably leaks in, such as the wrapped vs. unwrapped mode. Wrapping a "document" with an operation name is certainly not RESTful!

    CXF's effort is in many ways similar to what Microsoft has done with the HTTP support in WCF. I can certainly appreciate the fact that time-to-market is lower when building on top of an existing comprehensive framework, but when the abstractions of the existing framework differ fundamentally from those of the new one, the developer experience is inevitably affected.
Ok, there are some parts I don't like as much:
  • No out-of-the-box Spring integration. Spring is the IoC container of choice of much of the Java world at the moment, and any framework that integrates with it, like CXF, has a clear advantage.

  • Hard-coded dependencies mean customisation is hard. I can't easily inject my own classes to achieve the functionality I want. Also, quite a few classes are final for no apparent reason.
One of my colleagues, Gianny Damour, pointed me to CXF's effort to support JAX-RS, currently in one of their branches. This could be very interesting!