Hi,
On 07/02/12 14:29, hdave wrote:
Sergey,
Thanks for the idea...that sounds exactly like the kind of "back door" I
need to get this done. Will study that today.
Regarding the hypermedia links themselves, there are a number of
proposals
out there for a standardized way to add link relations to REST payloads.
Some folks advocate using HTTP Link headers. While this solution
offers the
added benefit of allowing an HTTP HEAD call to return just the links,
it is
incomplete as embedded subresources must have their own links.
There is a REST framework called Restfulie
(http://restfulie.caelum.com.br/)
that I have looked at only briefly. It has a way to embed the links,
though
I don't think it is very transparent and doesn't use annotations for it
(I've spent a grand total of 15 minutes studying it).
Another standard I have looked at is called HAL
(http://stateless.co/hal_specification.html). It is an interesting
proposal, but I believe any standard for representing links should not BE
the media type, but rather affect the media type in some standard way.
Yet others advocate using the XML link element from the ATOM syndication
format. I probably fall more into this camp, however I don't see the
advantage (someone enlighten me please) to literally re-using the XML
namespace and schema of Atom.
Thanks for this summary.
FYI, this is what is proposed to be supported in JAX-RS 2.0:
http://java.net/projects/jax-rs-spec/pages/HypermediaExample
Currently it's about the Link headers, I see the current proposal being
very good in simplifying the way such headers can be created or
extracted. There's an opinion that it's a bit early to standardize on
the other related options given the community is continuing with
experimenting in this area, which I agree makes sense for now.
I propose to embed atom-like link objects into the XML elements not as
attributes, nor as sibling to the entity either, but rather as child
elements. Something that could look like this:
--------------------------------------------
<foo id="123">
<name>myFoo</name>
<description>Another kind of foo altogether.</description>
<links>
<link rel="self" href="http://myserver.com/foos/123" method="get"
type="application/mything+xml">
<link rel="previous" href="http://myserver.com/foos/122"
type="application/mything+xml">
<link rel="next" href="http://myserver.com/foos/124"
type="application/mything+xml">
<link rel="edit" href="http://myserver.com/foos/123"
type="application/html-form+xml">
<link rel="cancel" href="http://myserver.com/foos/123?op="cancel""
method="post" type="application/mything+xml">
</links>
</foo>
--------------------------------------------
Part of the reason for the element wrapper "<links>" is to that the
payload
could be marshalled to JSON cleanly as well.
what I'm a bit pessimistic about, is the fact that the link elements (or
attributes) will become part of the actual foo's content where 'foo' is
a specific domain object. This is XML, not (X)HTML, presumably to be
consumed by a client code. Will that code cope with the possible
validation against the schema with the foo element having say a closed
content model ?
The other thing which I referred to in the previous email, is this. It's
kind of next to impossible to guess the values such as 124 & 123 in your
example above at the level of the annotation, some basic 'guesses' can
be done say, assuming the value of the current @PathParam is 121 then
the prev link must be ending with 120, the next with 122. etc, but it's
not going to work as a general solution.
Ideally, one would indeed have a bean property such as 'String href' or
List, etc, but as you said you have an existing rich model and neither
updating it all nor adding an adapter per every domain object is
practical, so it's quite compelling to get the right runtime support for
it.
IMHO the answer is in determining who the actual consumer is.
If this payload were to be processed and converted into HTML then may be
a better option return a container bean which RequestDispatcherProvider
will make available to JSP or similar, example:
@GET
public ContainerBean get(@Context UriInfo ui) {
ContainerBean bean = new ContainerBean();
Foo foo = new Foo();
bean.setDomainObject(foo);
List<Link> links = calculateAbsoluteLinks(foo, ui);
bean.setLinks(links);
return bean;
}
The JSP/etc will show the contents of Foo and will nicely add links for
a user to explore...
And what about using the Atom itself for a case when embedding links
within the content is assumed to be OK ?
What are your thoughts about it ?
Now, having said it all, I agree it does make sense to let people
transparently embed the links within the actual payload - the client
won't mind or for the sake of letting experiment with this specific
approach...So,
I have not decided on the all the attributes of the "Link" class, but
here
is what I am thinking:
For sure:
rel - link relation URI. I am planning on reusing IANA ones where it
makes sense and inventing them for my application as needed
OK
href - hypermedia reference. URL to dereference. Not sure if it should
be absolute or relative yet. Maybe it could be both. I think it will need
to be a URI template sometimes.
OK - it will need to be a relative URI to be resolved against the
current URI (base or request one)
method - HTTP method to use
Not sure about this one, the client needs to have an idea what to do
with the link and as far as the generic client is concerned it will need
to be GET I guess
title - Optional human readable short name for this link
The 'rel' seems to fit the purpose well too
Maybe?:
description - Optional longer (e.g. 1 sentence) human readable
explanation of the link
OK
types - Optional list of available media types for the response. Could
cut down on unnecessary con-neg if used by clients
Similarly to the method, I expect the clients know what they need to do
with the payload the links may return given that they've consumed the
payload containing the links, may be we can experiment with this
particular one later... ?
Because these hypermedia links are only used in REST (e.g. not SOAP) I
would
want the links to be inserted as part of the marshaling process when in a
REST context. It's important that the XML payloads for SOAP not be
cluttered up with this noise. Yet, the structure of the links needs to be
included in any generated XML schema file else schema validation will
fail.
I have no idea how to handle that.
well, this is what I was referring to above and to be honest I've no
idea it is even possible to auto-generate a new updated schema for 'foo'
based on its original one
Again, there is no unmarshaling
required.
So, if not, then how important you see supporting the embedded links
within the content of individual domain objects is ?
Which hypermedia links are available for any given object is a
function of
that object's state at the time of marshaling. Thus I do not think
this can
be handled by static annotations, because you need to compute the
applicability of each link relation based on (potentially internal)
properties. With no other idea on the table, I was planning on using the
visitor pattern to accomplish this. That is, I would create a function
object that, when given the object to be marshaled, would compute the
hypermedia link objects and "do something" with them. Presumably, the
function object would use the URL builder APIs.
Right...So are you open to doing it by customizing the marshalling
process with the help of the custom writer ? I'm not yet following how
this function object will be plugged in into the process...
I do agree that using static annotations is kind of limited.
So, what are we going to do with Link annotations ? If we can figure out
how to add