users@jersey.java.net

Re: [Jersey] Generating WS client based on reflection

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 03 Dec 2009 13:12:59 +0100

On Dec 3, 2009, at 11:20 AM, gerard davison wrote:

>
>
> On 02/12/2009 14:47, Paul Sandoz wrote:
>>
>>
>> On Dec 2, 2009, at 3:10 PM, gerard davison wrote:
>>
>>>
>>> Hi,
>>>
>>> Unfortunately my implementation of this is still stuck with legal
>>> but I do hope to contribute it to the Jersey project at some point
>>> in the future. I do agree generally with what Paul has said about
>>> the content type challenges and the inadvisability of trying the
>>> share the interfaces between clients and servers. Some of more
>>> thoughts on this topic are here:
>>>
>>> http://kingsfleet.blogspot.com/2009/10/proxy-client-based-on-jersey-with-bit.html
>>>
>>> I have taken it a little bit further on the server side to allow a
>>> similar model; but I haven't had time to write this up as yet.
>>>
>>> One solution to the mutliple content type challenge that occurred
>>> to us is that if you are generating a java API it would make sense
>>> to pick at this point which content type you wanted. This only
>>> works is you have a consistent content type of course. The other
>>> workarounds are to have the client interface return ClientResponse
>>> where the user can select there own type and of course to generate
>>> a method for each. (I have gotten the ClientResponse version
>>> working easily, I think RESTEasy use the same solution)
>>>
>>> Another thing you need to consider is how to deal with sub
>>> resources, this is where the proxing method start to look more
>>> interesting when compared to the client fluent interface.
>>>
>>
>> What about if there were an easier way to obtain resources from
>> links in representations? including say from the Location or Link
>> headers.
>
> I kind of have it working for both cases, so you can do the
> following if the return type of the method is an interface with some
> @Path annotations:
>
> Account acc = banks.getBank("Tusco").getAccount("une");
>
> But also if the invocation returns a Location header you can do the
> following, in this case the POST that returns a 201 created:
>
> Transaction t = acc.createTranaction(transactionBean);
>

How do you think this would look if one were not proxy to resources
but to links of representations (be it headers or in the content)?
i.e. the client side does not use @Path as the links are declared by
server in the returned representations.

Warning brain dump mode...

   WebResource r = ...
   Purchase b = r.get(Purchase.class)

   OrderType ot = ...
   Order o = p.purchase(ot); // This performs a post on an appropriate
URI declared
                                                 // in representation
returned from initial GET request

   o.update(ot);
   WebResource or = o.getResource();
   or.delete();


Purchase is not a JAXB bean but a proxy that knows about possible link
types returned in the representation of r. Thus Purchase may be
defined in terms of link types and maybe XPath expressions.

I know there are cases for services that are not fully hypermedia
enabled where such ease of use APIs could still be helpful, but i
wonder if we manage to nail the full hypermedia case we might be able
to build on top of that for other cases.



> This creates a proxy with a URL based on the Location header, if
> memory serves me right then if there is no location header null is
> returned, or I guess the client might throw an exception.
>
> I have not thought about Link headers before, ideally I guess these
> could be generated transparently on the server side and on the
> client they would just surface as accessors. How would that map to
> WADL though? (I am as every obsessed by the idea of wanting to
> generate these interfaces)
>

:-) I am not sure, need some input from Marc, on how WADL could be
used/extended to support link types in headers and representations.

Paul.



>
>>
>>
>>> I am going to have to ponder that Ruby example a little bit to see
>>> if we can build something similar using Java, there are some
>>> interesting ideas there. I guess by typed you mean the "rel" value.
>>
>> Yes.
>>
>> But i think other patterns might also apply, even if they are less
>> flexible or more coupled than typed links, using perhaps general
>> XPathy like expressions.
>
>
> Possible, will have a think,
>
> Gerard
>
>>
>> Paul.
>>
>>> This should be possible using the existing mechanisms in JAXB.
>>>
>>> Cheers,
>>>
>>> Gerard
>>>
>>>
>>> On 01/12/2009 09:25, Paul Sandoz wrote:
>>>>
>>>> Hi Jean,
>>>>
>>>> A proxy-based client-side solution has been discussed, but there
>>>> is nothing implemented in Jersey to support this. Notably, Gerard
>>>> Davidson has some ideas in this area.
>>>>
>>>> My opinion is that such proxies, as you present, unduly
>>>> encourages the coupling of the client to the server and it really
>>>> does not give much over utilizing the Jersey client API as of
>>>> today, for example:
>>>>
>>>> Client c = Client.create();
>>>> URI u = ...
>>>> UriBuilder ub = UriBuilder.fromUri(u).path("product/{id}");
>>>>
>>>> ProductConverter pc =
>>>> c.resource(ub.build(1)).get(ProductConverter.class);
>>>> c.resource(ub.build(2)).put(new ProductConverter());
>>>>
>>>> Or creating a simple ProductResource class that encapsulates the
>>>> above. Note that in your ProductResource interface there is no
>>>> way the client can distinguish between XML or JSON.
>>>>
>>>> I think the main advantage to any proxy-based solution is in
>>>> terms of documentation and especially when utilized with IDEs.
>>>>
>>>> What i would really like to see is a focus on proxy-based
>>>> solutions for *representations* supporting typed links. That IMHO
>>>> is the right place for proxying or even static code generation as
>>>> the media types and link types are important types for hypermedia
>>>> processing. There has been some nice work w.r.t. in Ruby:
>>>>
>>>> http://www.infoq.com/news/2009/11/restfulie-hypermedia-services
>>>>
>>>> Any exploration of the client area also needs to be coupled with
>>>> solutions on the server-side for supporting typed links.
>>>>
>>>> Paul.
>>>>
>>>> On Dec 1, 2009, at 3:14 AM, Jean Aurambault wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I'm thinking about a way of generating automatically clients for
>>>>> a WS based on reflection. Could be by sharing the WS definition
>>>>> in an interface or even using directly a jersey annotated
>>>>> class... Let's say with an interface it would be something like
>>>>> this:
>>>>>
>>>>> public interface ProductResource {
>>>>>
>>>>> @Path("/product/{id}")
>>>>> @GET
>>>>> @Produces({"application/xml", "application/json"})
>>>>> public ProductConverter get(@PathParam("id") int id);
>>>>>
>>>>> @Path("/product/{id}")
>>>>> @PUT
>>>>> @Consumes({"application/xml", "application/json"})
>>>>> public void put(@PathParam("id") int id, ProductConverter
>>>>> productConverter);
>>>>> }
>>>>>
>>>>> the server would implement the interface
>>>>>
>>>>> public class ProductResourceServerImpl implements
>>>>> ProductResource {
>>>>> ...
>>>>> }
>>>>>
>>>>> And on the client side having something like this:
>>>>>
>>>>> Client client = new Client();
>>>>> ProductResource pr = client.resource(ProductResource.class);
>>>>> ProductConverter product = pr.get(1);
>>>>> pr.put(2, new ProductConverter());
>>>>>
>>>>> Is there anything close to this available? Any thoughts?
>>>>>
>>>>> best regards,
>>>>>
>>>>> Jean
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> 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
>>>
>>
>
> --
> 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