[Moving this thread to the user's list]
Gerard,
Thanks for the pointers to your blog and for elaborating your ideas.
I can see how this can be useful for tooling and for improving ease of
use.
I'm putting together a wiki with some .next ideas for REST [1]. Most
of which are being discussed in blogs and papers by other authors. The
section entitled "The Need for Better Client APIs" in that wiki
outlines some of the goals for a .next client API that the majority of
the community seems to agree on (there may be a few more that I have
missed).
I believe that your proposal addresses (2) in that list quite well
and also gets us closer to (1) and (3). My thoughts on (1) are the
following:
i) At its core JAX-RS defines a mapping between URI operations and
resource methods. This mapping is dynamic and guided by annotations in
server-side resource classes.
ii) The proxy based client APIs that are being proposed define a
mapping between resource methods and URI operations (the inverse of
(i)). As proposed, the mapping is dynamic and guided by annotations in
client-side resource classes (or interfaces).
Given the importance of server evolution, (ii) has to be thought out
carefully to avoid excessive coupling. This is key to enable (1).
Instead of using annotations on client-side resource classes to
guide the mapping, I wonder if it's possible to use dynamic
information obtained from the server. This would clearly enable the
server to evolve more freely. Moreover, this relates to (3) given that
resource transitions (as in HATEOAS) should ideally be handled in the
same way. That is, perhaps all the interactions between clients and
servers can be based on these resource transitions.
Following the HATEAOS constraint, every resource representation
returns a set of transitions (some of which may be self transitions,
causing the server to transitions back to the same state). Other than
with the root resource, client developers interact with resources
using these transitions (which means they must know at least a subset
of them statically even if they don't know how they map to URI
operations) without relying on additional static information such as
that conveyed by client-side annotations. That is, the client runtime
will map proxy calls to URI operations based on information it
received from the server rather than information already known to the
client.
I realize there's a lot to be fleshed out here :) What do you think
so far?
-- Santiago
[1]
http://wikis.sun.com/display/Jersey/Hypermedia+and+Client+APIs
On Dec 4, 2009, at 1:45 PM, gerard davison wrote:
>>
>>> JDeveloper is a kinda of 3-4GL tool so some of our users need
>>> quite a bit of guidance. We knew we wanted something that looked
>>> and worked like JSR 311 rather than the generator Marc up together
>>> for the wadl project so as Paul will tell you I have been playing
>>> with various ideas with a dynamic Proxy. Of course that led to me
>>> playing with HATEOAS as with all things restful in general but I
>>> am not just focused on the client side that is just where I
>>> started playing about.
>>
>> Is it fair to say that what you have in mind now is similar to
>> RESTeasy's client framework [1]?
>
> Yes, but for example RESTeasy doesn't, at least in the
> documentation, appear to support sub resources correctly. Not that
> it took a lot of work to implement it. Also specifically I want
> proxies and resource classes to be able to be persisted as first
> class elements via JAX-B. Some of my current thoughts are here; but
> that doesn't really cover the sever side yet. Not had time to write
> those up.
>
> http://kingsfleet.blogspot.com/2009/09/javalangreflectproxy-client-based-on.html
> http://kingsfleet.blogspot.com/2009/10/proxy-client-based-on-jersey-with-bit.html
>
> The other fun things you can do with proxies is allow the user to
> control of specific parts of the API. For example if you edit the
> interface to be:
>
> {
> @GET
> public Future<Bean> getBean()
> }
>
> You can intuit that the user want an async interface, or indeed to
> please Jeanfrancois you could do the following to give a simple long
> pooling interface:
>
> {
> @GET
> Iterator<Future<Bean>> getBean();
> }
>
> Or I guess following on from the Links/Header discussion over the
> last few days, though be aware that I probably haven't thought his
> one through enough.
>
> public interface GenericNexus<Entity, Resource>
> {
> public Entity getBean();
> public Resource getSelf()
> }
>
>
> public interface GenericDeleteResource
> {
> @DELETE
> public Reponse.Status delete();
> }
>
> public interface BeanNexus
> extends GenericNexus<Bean, BeanResource>
> {
>
> @LinkHeader(rel="next");
> public BeanResource getNextBean();
> @LinkHeader(rel="last");
> public BeanResource getLastBean();
>
> @LinkHeader(rel="delete");
> public GenericDeleteResource delete();
>
> }
>
> public interface BeanResource
> {
> @GET
> BeanNexus getBean();
> }
>
> //
>
> BeanResource br = ...;
> BeanNexus bn = br.getBean();
> Bean bean = bn.getEntity();
> BeanResource = bn.getNextBean();
>
>
> I guess the thing about proxies is that if you can describe a java
> interface with a reasonable pattern you can quite easily implement
> that functionality on the back end.
>
> Gerard
>