users@jersey.java.net

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

From: Markus Karg <markus.karg_at_gmx.net>
Date: Mon, 15 Feb 2010 21:52:32 +0100

> > 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.

This is brilliant and 100% pure REST! Congratulations, you'll have my vote!
:-)

> > 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.

The question is whether this is actually useful, as a client requesting a
PDF obviously would be able to understand PDF already. So what shall it be
good for? Also, XML and JSON are not formats but meta formats: The actual
format would be "application/SAP-order-document+xml" for example, which is
syntactically XML and might already define XLinks in it's XSD. So you cannot
just assume that there will be plain XML with XLinks at any particular place
in the document! Remember the HTML example: There will be no explicit <a>
list at a particular place, but the client is free to click ANY (!) <a> it
finds. In other words, ANY (!) XLink in XML is a valid state change trigger,
you cannot have an API supporting that unless it would extract ANY XLink --
not just the ones your server has woven it, but also the ones the content
already contained statically (e. g. by obtaining it from a backend or
template)!
 
> 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.

As I said, I doubt it. Fielding's dissertation is clear in the description
that a RESTful client *must* do what a browser does and *not* do any
assumptions about what the content *should* be like, but it *must* process
the content as it comes from the server. Otherwise you would tie the client
API to the server API, which is not what REST is about. Take care of loose
binding!

> 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.

As I said, I don't see actually a need for it, as all examples checked so
far are not RESTful but try to do RPC-via-http, which is NOT REST.

> > 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.

Maybe (no: actually!) I missed the start of the discussion, so I possibly
could better understand what you actually try to achieve with that
"hypermedia support" if you could write in short what you actual problem
with the current JAX-RS API is? Remember, I did not write that the proposal
is shit ;-) , I wrote that it is not REST and especially I wrote that it is
just useless. Why? Because I do not see that JAX-RS is missing something.
People *can* do HATEOAS with JAX-RS 1.1. The fact that there is no special
stuff in JAX-RS for HATEOAS does not mean that there *must* or at least
*should* be some stuff. See, if I want to do what Fielding says, I can do
that with JAX-RS without any real problem. So why adding a solution if there
is no real problem? Or maybe I do not see the problem because I am using XML
and adding an XLink is not really a problem in Java...?

Regards
Markus