users@jersey.java.net

Re: [Jersey] "Real" HATEOAS support for JAX-RS

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 15 Feb 2010 14:35:08 -0500

On Feb 15, 2010, at 1:56 PM, Markus Karg wrote:

> Building on Fielding's (and only Fielding's) actualy words in his blog and dissertation (what lead to my blog entry yesterday) I'd like to propose a different API for hypermedia support:
>
> Fielding wants RESTful applications to have state information found inside of the document (see http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven), so the question is, how this can be supported by JAX-RS?
>
> On the server side, there must be something (let's call it "MessageBodyEnricher") that is able to modify URIs INSIDE of entities. Just as JAX-RS already supports CREATION of entities from Java objects by an extensible framework (MessageBodyWriter), there needs to be an extensible framework for ENRICHMENT of entities with a supplied list of links ("MessageBodyEnricher"). I could imagine that MessageBodyWriter just gets an additional set of methods for adding URIs valid in the current state. The MessageBodyWrite would then process the links by adding it into the binary result. Example: If the result is HTML, the enrichment would be adding a list of <a>. That is exactly the example fielding gave in his dissertation. As more typical message bodies are e. g. XML, the enrichment must happen by adding XLinks at time of message body writing.
>
I had a slightly different approach in mind, as I wrote in an earlier thread:

> One of the things I'm keen to tackle in a follow-on JSR is support for declarative hyperlinking in representations. To give a flavor of the kind of thing I'd like to see possible in beans returned from resource methods:
>
> // extracts URI template from resource class and fills in any template vars
> // using the values of properties of the representation bean
> @Link(resource=SomeResource.class)
> private URI self;
>
> // creates a URI from a template using embedded EL expressions
> @Link(template="type/${type}")
> private URI self;
>
> We'll need to experiment with this a bit to get the right level of support and ease-of-use.

MessageBodyWriters will remain responsible for converting the representation bean to some media type, the values of links in the bean will be set before the MBW is called. Maybe we also need something like you suggest (essentially an interceptor/filter framework) but I think for link creation a standard declarative approach would help a lot.

> On the client side, there must be just NOTHING as the client typically is able to parse and understand the received content. Example: If the result is HTML and the client is a browser, it will understand the contained list of <a> and the user selects one and clicks it. A more typical message body will be e. g. XML, so the client software will understand the XML schema's semantics and pick the right XLink from it, on discretion of the workflow it wants to drive.
>
I think it will be possible to go a step beyond "NOTHING" without tying JAX-RS to a particular hypermedia approach. E.g. we could provide APIs that simplify link identification and extraction for common formats like XML or JSON.

For JAX-RS that may be all we can manage. However, I think its quite reasonable for Jersey to experiment with additional layers of functionality. I'm hopeful that some of that experimentation will influence the facilities provided by JAX-RS to make building such additional layers easier even if JAX-RS doesn't provide them directly.

> This is a 1:1 translation of what the dissertation and Fielding's above blog entry tells us, it is 100% HATEOAS and REST, it is independent of the protocol. But it might be not what you like to get or like to do?
>
Personally, having written a lot of client code using the current Jersey client API, I'd like something more declarative but I don't think that current annotated interface approaches are good enough since they introduce design-time tight coupling to URIs and methods. Hence the current investigation.

Marc.