RESTful Web Services in Java
Ive been soaking up pretty much everything I can find on REST recently. Some time ago I was about to start a new human web project, and thought designing it RESTfully might possibly be a good idea. Since then, I have read Sam Ruby/Leonard Richardson's excellent tome RESTful Web Services, and have become convinced that it is.
Being a long time Spring advocate, I have watched closely the gradual emergence of Spring 3.0, which is looking to fill in a lot of its gaps in REST support. Most interestingly, its server side implementation has come as the next great adventure with Spring MVC, and not its already mature Web Services effort framework.
Spring of course is certainly not alone, or anywhere near first in this area with several significant projects arguably at a much greater level of maturity.
JAX-RS (JSR-311)
The main non-Spring thrust for RESTful WS in Java, has become centered around the recently finalised JSR-311, known as JAX-RS. This is not to say that the RESTful Java story begins with a Sun standard (perish the thought). At least one of the RESTful java efforts (RESTlet) predated JSR-311 quite significantly, but is now an adoptee of the JSR. There are at least the following open source implementations that I know of:
- Jersey
- Restlet
- RestEasy
- Apache CXF
- Apache Wink
Of these, the only one I have spent any real time kicking the tyres on is Jersey. Although this is billed as the reference implementation from Sun, it seems to have some ambitions to penetrate the real world a lot further than other reference rollouts that Sun have provided in the past. So far, my entire experience of JAX-RS is limited to Jersey, so I wont trouble you with my as yet non-expert opinion of these, expecially as Solomon Duskis has been working on a comparrison of these implementations.
I will note though just a few things did strike me very quickly when running through a few representative scenarios with Jersey:
- The annotated API looks intuitive. With classes representing (Restful) Resources, and some easily recognisable annotations such as @GET, and @POST, etc. The initial learning curve looks pretty manageable.
- Getting started with Jersey is trivial. This is really just a credit to the good work done by the Sun guys, to provide lots of easy entry points to their project, including some useful maven2 archetypes that get you up and running with an executable (albeit Grizzly WebServer hosted) Hello World service, quicker than you can say "HATEOAS".
- Resource Instances per Request?. Instances of the Resource classes appear to be instantiated on every request. That I am suprised by this, could just be the newb in me showing. More likely it is coming from a Spring MVC Controller standpoint whereby the handler of the request is a managed global singleton. This wasnt immediately obvious from running a Hello World example as these only support GET, but as soon as I wanted to implement a mutative method like POST(a) I realised I was in trouble.
I would think that the Resource-Object-Created-On-Request pattern would not lend itself so well to dependecy injection frameworks like Spring which prefer to create upfront, and directly manage beans. Im sure there are plenty of ways around this, but it didnt seem to be the most natural approach. Perhaps this is the reason why the Spring guys did not themselves go down the JAX-RS route?
Other non-JAX-RS efforts
With the relative freshness of JSR-311, there are other efforts as well floating around that havent adhered to the spec. Other than Spring 3.0 itself, one worth noting is Josh Devins Mattress Framework. Josh also notes the Resource-Object-Created-On-Request pattern as a reason for not adhering to the spec. With very little community involvement however, rather than Mattress becoming a major player, its largest contribution may be to provide a running, mostly functional technical comparrison to JAX-RS.
Certainly for those who have been burnt in the past by Sun's 'spec first' approach, lightweight functional alternatives are always great to see.
Client Support
One area with possibly the greatest divergence is that of support for the client. Spring is offering its RestTemplate in the style of other boilerplate-hiding templates that they have proved successful with. Others in the JAX-RS camp have been reusing aspects of the spec on the client side, even though this is beyond scope of the spec itself.
What Im looking for
I am very interested to see how Solomon's comparrison progresses, not only to know which (if any) technology is worth investing my time (ahem career) in utilising, but also to see what method he takes in comparrison. Hopefully the same approach can be expanded to consider the effectiveness of non-JAX-RS efforts.
Im also interested to know if there is a reference application out there (preferably not involving any more pets or pet stores!) that might be useful in such a comparrison of frameworks.
Finally I am interested to see how successful any of these approaches are in providing for server side convergence of runtime code supporting both the human web and the machine web. How can architect the server side for a future that embraces both humans and machines as clients of the same resources? Building out on their MVC framework puts Spring well down this path, but is their new REST support strong enough?
Update. A couple of other JAX-RS implementations that are floating around:
- Apache Wink - looks to largely be a new collaboration between teams at HP and IBM
- Triaxrs - which appears to be gunning for the OSGi space
Good to see some more activity.
W3C friendly links with JSTL Core URL tag
The JSTL Core tag library offers a really useful url tag for generating URLs for html links from within JSP. This is particularly useful when there are one or request parameters that need to be carried along with the URI. They can be specified like this:
<a href="<c:url value="/next.htm">
<c:param name="personId" value="${person.id}"/>
<c:param name="preferredTitle" value="Mr"/>
</c:url>"/>
In this example there are two request parameters. The first (personId) is resolved from an in scope variable, and the second (preferredTitle) is supplied directly to the tag. This would produce something like the following:
<a href="/next.htm?personId=5&preferredTitle=Mr" />
The problem
Whilst this may work in your browser, by default, (at least with JSTL 1.1) the URL produced does not validate with respect to the W3C standards. This is because the produced link contains an unescaped ampersand to separate the request parameters:
next.htm?personId=5&preferredTitle=Mr
The problem of course is not so much the ampersand itself, as the fact that it has been left unescaped when the link was rendered.
One possible solution
... is to use the JSTL Core out tag when producing the href link like this:
<c:url var="nextLink" value="/next.htm">
<c:param name="personId" value="${person.id}"/>
<c:param name="preferredTitle" value="Mr"/>
</c:url>
<a href="<c:out value="${nextLink}" escapeXml="true" />">
Adding the var attribute assigns the generated URL to the in scope variable nextLink. This allows the subsequent c:out to access the generated URL. Because c:out supports the escape of XML characters, the ampersand separating the request parameters is resolved to its escaped format &
- which makes Mr W3C very happy indeed!