Sunday, January 04, 2009

JAX-RS and HATEOAS

This post should have been named something like: "JAX-RS should provide a way to identify and resolve resource URLs".
However, it was too long, so I opted for some buzzy acronyms: let me explain them.

JAX-RS is the official Java API for building Restful Web Services: also known as JSR-311, it went final a few months ago, and is, IMHO, a very good specification, providing an easy and effective way for building REST-oriented web services.
http://www.blogger.com/img/blank.gif

HATEOAS is something more complicated: it would deserve a whole post by its own, but I will try to explain it in a few paragraphs.
First, HATEOAS ishttp://www.blogger.com/img/blank.gif an acronym for: Hypermedia As The Engine Of Application State.
Wow ... you may wonder what does it meahttp://www.blogger.com/img/blank.gifn, so ...
Everyone knows about REST, but too bad, not everyone knows that it's an architectural style, rather than an implementation thing.
More specifically, REST is a way for creating distributed (web) architectures based on some basic principles, and HATEOAS is one of the most important, and often misled/ignored.
HATEOAS could also be named hypermedia-based navigation. It means that a REST application should provide at most one fixed URL: all application URLs, with related resources, should be "dynamically" discovered, and navigated, starting from that fixed URL, thanks to the use of hypermedia links throughout all resources.

That said, the concept of resource URL acquires great relevance: every resource must have its own URL, and that URL must be known by other resources in order to publish it and make the resource accessible.

Now, let's go to my point.
JAX-RS does a very good job at defining resource URLs, but lacks of a way for identifying, as a first class concept, what is the actual URL of a given resource, and hence for resolving it.
Let me give a simple example.
Take a look at the following JAX-RS compliant web resource implementation:

@Path("/resources")
private static class JAXRSResource {

@GET
@Path("/resource")
public String getResource() {
// ...
}

@POST
@Path("/")
public void postResource(String resource) {
// ...
}
}

It defines how to GET and POST the resource, with related paths, but how does it define what really is the URL to use for identifying the resource? And how could another resource refer to it?
For answering the first question, you have to browse all methods, and guess the correct one by looking at the http method annotation (GET), plus its path values.
For answering the second question, you have to hard-code it in the referring resource, or write something like (using JAX-RS APIs) UriBuilder.fromResource(JAXRSResource.class).path(JAXRSResource.class, "getResource").build(): both obscure and error-prone.

So here is my point: again, JAX-RS should provide a way for clearly identifying a resource URL, and easily resolving it.

What do you think?

4 comments:

James Strachan said...

Good post :)

Its not in any way a complete solution, but to help folks identify all of the various URIs available in your application you can point folks using Jersey at

/application.wadl

and then you'll get a blob of XML with all the URI patterns that the application supports which at least helps and tools like http://enunciate.codehaus.org/ can produce better documentation etc

Sergio Bossa said...

Thanks for your comment, James.

I will take a look at WADL support, but it's just half of the story: JAX-RS still lacks of a way to programmatically identify and resolve resources, regardless of the way you describe them.
I had to implement such a thing by myself for a project I'm working on, following the "specification" described here in my posts.

Cheers,

Sergio B.

hugginss jetterees said...

Microsoft on Tuesday revealed plans to purchase Nokia's device and services division microsoft office 2011 for mac product key for $7.two billion. The enterprise views the deal as its method to get far more traction within a smartphone marketplace at the moment dominated by Apple and Samsung. It is also office professional plus 2010 retail pack a way for Microsoft to grow to be a lot more Apple-like, controlling both hardware and software program.

Caleb Cushing said...

I know this was written a while ago, but this works in JAX-RS 2


@Context
UriInfo uriInfo;
...
uriInfo.getBaseUriBuilder()
.path( ActivitiesCtrlr.class )
.path( ActivitiesCtrlr.class, "get" )
.build( activityId );