users@jersey.java.net

Re: [Jersey] Re: Hypermedia for JAX-RS/Jersey clients and server

From: gerard davison <gerard.davison_at_oracle.com>
Date: Thu, 10 Dec 2009 15:52:53 +0000

Just to note these are general comments rather than a reply to this
specific message, excuse the long email as I have been out of the loop
for a few days.


* Flavours of HATEOAS *

It seem that before we work out what should and shouldn't be supported
with regards to HATEOAS we should first try to list al the flavours and
subtypes. In my limited experience here are a few subdivisions that we
might want to consider when writing clients. I wanted to write this down
at least for my own benefit.

~~~~

1. Implicit / Derived links

1.1 Implicit (aka Legacy services)

In this case the entity object contains values that can be at the client
end be used to derive outgoing links. This most obvious version of this
is a service that doesn't know it could be HATEOAS, for example it
returns the following information:

<employee>
<name>Bob</name>
<start-date>01-JAN-2006</start-date>
<department>46</department>
</employee>

There is no technical reason why this cannot be surfaced on the client
side as something like this:

@XmlRootElement(...)
public class Employee
{
      String getName();
      Date getStartDate();
      DepartmentResource getDepartment();
}

The department resource being annotated with a type adapter which knows
how to convert department into a uri -> proxy. I have a least one system
here at Oracle that would need support along these lines.

1.2 Derived

Some modern REST apis, for example LinkedIn, use URIs that don't use the
HTTP protocol:

http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment
(see slide 9, although the rest of the presentation is very interesting)

In this case on the client side we need some kind of mapping between the
data model uri and the http uri. This to me just seems like a special
case of the implicit links. (Or should it be a special case of explicit
links)

<employee>
<name>Bob</name>
<start-date>01-JAN-2006</start-date>
<department>urn:hr:department/46</department>
</employee>

2. Explicit links

Explicit links to resources that can be directly referenced.

2.1 Generic in the entity

<employee>
<name>Bob</name>
<start-date>01-JAN-2006</start-date>
<department>http://www.example.com/hr/deparment/46</department>
</employee>

2.2 Using Atom or some other description format

These can have some meaning

<employee>
<name>Bob</name>
<start-date>01-JAN-2006</start-date>
<atom:link rel="parent">http://www.example.com/hr/deparment</atom:link>
</employee>

3. Out of band links.

3.1 HTTP-Headers

For example using HTTP Header Linking:

http://www.mnot.net/drafts/draft-nottingham-http-link-header-00.txt

Of course this binds your implementation to HTTP in a way you might live
to regret at a later stage. Think of all the work that goes into
supporting SOAP over non HTTP protocols.

~~~~

In general it should be possible for a generic client to support of all
these options, it is just a matter of coming up with the correct API.
The HTTP headers is a difficult one as the information out out of bounds
of the entity. So the most obvious design choices are:

1. Interim proxy object

EmployeeResource er = ...
EmployeeEntity ee = er.getEmployee();
Employee e = ee.getEntity(); // Actual entity on the wire
ee.delete(); // State transition on the
proxy object

2. Injected into the entity object

@XmlRootElement(...)
public class Employee
{
      @LinkHeader()
      DeleteResource delete();
      String getName();
      Date getStartDate();
      DepartmentResource getDepartment();
}

If you are generating the client model classes you can of course inject
any information you want into there, and extract it later. This of
course wouldn't work so well if you are just performing a HEAD to get
the transitions.

3. Fetch generically from the Response object

EmployeeResource er = ...
Response<EmployeeEntity> response = er.getEmployee();
response.transition("delete");

4. Use some JDK 7 features

http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001131.html

You could use the Dynamic features in JDK 7 to provide a nice API; but
code editors would need special coding to keep up.So you can have any
method you like defined at run time, very much like Ruby. But this is
going to make tooling harder.

http://code.joejag.com/2009/new-language-features-in-java-7/

The collection accessor feature could be used as follows; but I think
that having object implement Map for this reason is not the best idea.
Also it means that the interface is no longer type safe.

response["transition"].follow();


* Use cases *

It would be good to have a list of use cases that we are trying to
support. A few have been mentioned in the email thread; but it is always
good to list them out. I guess there are a few that come to mind:

"The client of the API would like a static interface with which to
program againsts. For the clients point of view this enabled them to use
existing coding tools that understand java interfaces and beans."

"The publisher of the API would like to define a subset of the WADL/IDL
for a client to use in a particular case. This would allow them to help
guide client in Java through a particular route in the API. "

This one came out of talking to some internal consultants working on
beehive, oracle's exchange like server that will one day replace the old
collaboration suite, which exposes at lot of RESTful APIs (The WADL is
huge). They would see it as being very valuable to be able to provide a
set of interfaces to say just perform email operation so that the user
can focus on the task in hand.

"The client of the API should be able to deal with the evolution of
server data model"

I guess practically this can be dealt with with versioned mime types in
some designs. I don't have enough experience to enumerate the possible
types, anybody care to take a stab? What is reasonable for the client to
be able to cope with.

One interesting API I have seen recently is the .net XPathDocument that
gives a really nice way to work with XML documents in a way that java
XPath doesn't:

http://msdn.microsoft.com/en-us/library/system.xml.xpath.xpathdocument.aspx

Would it be worth looking at best practices in this area? I guess if you
did want to use JAXB/JSON then the use of lots of "any" types in the
schema definition would help with evolution.

* Meta data terminology *

It is worth defining what is and what is not meta data. For example:

entity => m0 or instance data
wadl => m1 or meta data
links in http headers => is this m0 or m1? I am not sure we it contains
both instance references and information about the structure of the model


Hope some of this makes sense,

Gerard




On 10/12/2009 14:02, Paul Sandoz wrote:
>
> On Dec 10, 2009, at 2:39 PM, Santiago Pericas-Geertsen wrote:
>
>> Paul,
>>
>>>> I've started a "List of Requirements" section in the wiki [1] based
>>>> on this mail thread.
>>>>
>>>
>>> Great. I am not sure about requirement 1:
>>>
>>> 1) Meta-data about state transitions should not be part of a
>>> resource representation; instead it should be conveyed in HTTP
>>> headers or WADL documents, or both.
>>>
>>> Certain HTTP headers can be considered part of the representation
>>> i.e. representation == headers + entity.
>>
>> If by representation we include headers, then this requirement needs
>> to be re-phrased. I think the main point is that entities should not
>> be "artificially" extended to include state transitions information
>> or other meta-data (as discussed earlier in this thread). I think
>> Marc has a good point about this.
>>
>
> IIUC this captures the case when you have some existing entities that
> you cannot or do not want to modify?
>
>
>>>
>>> I suppose it depends on what you mean by meta-data, but typed links
>>> embedded in XML/JSON will contain data that the client can use to
>>> decide on whether to make a state transition (for example, HTML
>>> forms, plus this could get really interesting with RDF).
>>
>> Do you think typed links are enough to support HATEOAS?
>>
>
> I think they are mostly necessary (depending on how you specify things
> related to the media type), but are not sufficient if we want to
> improve the ability for machines communicate with each other (hence
> the reference to RDF, which is still being postulated as means for
> machines to better communicate). For now i think typed links are a
> good starting point to build upon.
>
>
>>>
>>> I think Link headers and links embedded in entities need to be
>>> supported, and those should be sufficient to declare state transitions.
>>
>> Right. I think the point of (1) is that what can go in Link headers
>> shouldn't be part of the entity.
>>
>
> Or vice versa, depending on the requirements?
>
> Using Link headers is a nice approach when one cannot or does not want
> to modify existing entities, or one does not want to place links in
> newly designed entities.
>
>
>>> WADLs role should be to help identify those links (reproducing data
>>> where required) in representations such that a client can use that
>>> at runtime or compile time to aid in the action of state
>>> transitions, but clients do not have to consume WADL if they do not
>>> want to.
>>
>> I agree. Do you want to take a stab at rephrasing the requirement?
>>
>
> OK. Before i do i would like to wait for a response from Marc.
>
> Paul.
>
>
>> -- Santiago
>>
>>>> On Dec 9, 2009, at 4:38 AM, Paul Sandoz wrote:
>>>>
>>>>>
>>>>> On Dec 8, 2009, at 10:56 PM, Marc Hadley wrote:
>>>>>
>>>>>> On Dec 8, 2009, at 2:34 PM, Marc Hadley wrote:
>>>>>>
>>>>>>> On Dec 8, 2009, at 2:08 PM, Santiago Pericas-Geertsen wrote:
>>>>>>>>
>>>>>>>> I want to make sure I understand and can capture all your points:
>>>>>>>>
>>>>>>>> 1) You *don't* think it's a good idea to extend resource
>>>>>>>> representations to include additional meta-data (using Atom or
>>>>>>>> otherwise) such as the following example from RESTfulie:
>>>>>>>>
>>>>>>>> <order>
>>>>>>>> <product>basic rails course</product>
>>>>>>>> <product>RESTful training</product>
>>>>>>>> <atom:link rel="refresh" href="
>>>>>>>> http://www.caelum.com.br/orders/1"
>>>>>>>> xmlns:atom="http://www.w3.org/2005/Atom
>>>>>>>> "/>
>>>>>>>> <atom:link rel="update" href="
>>>>>>>> http://www.caelum.com.br/orders/1"
>>>>>>>> xmlns:atom="http://www.w3.org/2005/Atom
>>>>>>>> "/>
>>>>>>>> <atom:link rel="pay" href="
>>>>>>>> http://www.caelum.com.br/orders/1/pay"
>>>>>>>> xmlns:atom="http://www.w3.org/2005/Atom
>>>>>>>> "/>
>>>>>>>> <atom:link rel="cancel" href="
>>>>>>>> http://www.caelum.com.br/orders/1"
>>>>>>>> xmlns:atom="http://www.w3.org/2005/Atom
>>>>>>>> "/>
>>>>>>>> </order>
>>>>>>>>
>>>>>>> Right. Up till now we've managed to keep JAX-RS at quite a
>>>>>>> meta-level and I don't think we should be in the business of
>>>>>>> defining what applications representations have to contain.
>>>>>>>
>>>>>>>>
>>>>>>>> 2) You'd prefer the use of HTTP headers to convey meta-data
>>>>>>>>
>>>>>>> Either headers or something like WADL that describes the links
>>>>>>> already available in representations. E.g. the information in
>>>>>>> the RESTfulie representation above could be split into data and
>>>>>>> metadata something like this:
>>>>>>>
>>>>>>> Link: <http://www.caelum.com.br/orders/1>; rel=refresh
>>>>>>> Link: <http://www.caelum.com.br/orders/1>; rel=update
>>>>>>> Link: <http://www.caelum.com.br/orders/1/pay>; rel=pay
>>>>>>> Link: <http://www.caelum.com.br/orders/1>; rel=cancel
>>>>>>>
>>>>>>> <order>
>>>>>>> <product>basic rails course</product>
>>>>>>> <product>RESTful training</product>
>>>>>>> </order>
>>>>>>>
>>>>>> BTW, I think it likely that existing representations could
>>>>>> include URIs so its equally important to be able to ascribe state
>>>>>> transition semantics to those without having to change the format
>>>>>> of the representation.
>>>>>>
>>>>>
>>>>> Yes, the key is not to dictate a particular solution or "style" to
>>>>> the way state transition links are embedded in representations.
>>>>>
>>>>> However, i think It should be easy for the developer to create a
>>>>> particular style, or latch on to an existing style (the link
>>>>> header approach in this respect is not so intrusive).
>>>>>
>>>>> Paul.
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

-- 
Gerard Davison | Senior Principal Software Engineer | +44 118 924 5095
Oracle JDeveloper Web Service, Spring, Weblogic SCA Tooling Development
Oracle Corporation UK Ltd is a company incorporated in England&  Wales.
Company Reg. No. 1782505.
Reg. office: Oracle Parkway, Thames Valley Park, Reading RG6 1RA.
Blog http://kingsfleet.blogspot.com Twitter kingsfleet