REST client implementation sample in progress + feedback request

283 views
Skip to first unread message

marius andreiana

unread,
Dec 12, 2010, 6:15:23 PM12/12/10
to GWTP
Hi,

Starting from the sample at http://code.google.com/p/gwt-platform/issues/detail?id=179
I started to implement a full REST client for a small app, using
http://code.google.com/p/google-web-toolkit/wiki/AutoBean instead of
piriti.

So far, the code looks like this:
* helper classes:
http://code.google.com/p/gwt-gae-book/source/browse/#svn/trunk/CultureShows/src/org/gwtgaebook/CultureShows/client/dispatch
* reading a list of location entities:
http://code.google.com/p/gwt-gae-book/source/browse/#svn/trunk/CultureShows/src/org/gwtgaebook/CultureShows/client/locations

I've listed some findings + TODO here
http://code.google.com/p/gwt-gae-book/wiki/GWTREST

What do you think about it?

zixzigma

unread,
Dec 12, 2010, 6:41:09 PM12/12/10
to GWTP
Thank you very much.
This is fantastic.

Your GWT-GAE Book is very great,
full of software engineering best practices,
and a thorough guide covering everything thats required to engineer a
serious application.

I am going to study the source code you provided.

Thank You

marius andreiana

unread,
Dec 13, 2010, 1:20:29 AM12/13/10
to GWTP
Glad you find it useful :)

Don't spend too much time on REST now, as it's work in progress. With
this group's help, hopefully we'll find the best way to use REST from
GWT.

I've updated the goals at http://code.google.com/p/gwt-gae-book/wiki/GWTREST
which resulted in an easier alternative (not using GWTP dispatch).

Waiting for the group feedback,
Marius

?mit

unread,
Dec 13, 2010, 9:28:56 AM12/13/10
to gwt-pl...@googlegroups.com
Hey marius, 

I also have to say: your GWT-GAE book was a grad read. 
Just curious, how does Autobean compare to piriti? I did just have a brief look at the Autobean documentation and I am not really sure what to think of it. 
It seems to support the same value types as piriti and also references are supported (however no JSON path). 
However I don't really understand how it maps to my model objects. With piriti you can define fields which are not parsed from/to Json and also define functions for client-side behaviour.
I have yet to understand how this is done with Autobean because it uses interfaces to define everything. (maybe you have an idea)

cheers
Uemit


Harald Pehl

unread,
Dec 13, 2010, 10:02:29 AM12/13/10
to gwt-pl...@googlegroups.com
Great overview, Marius! As I'm also writing an application (http://code.google.com/p/tire-d8/) using REST for the communication I'd like to contribute my two cents:

Alternatives:
In TiRe I'm using the alternative one: GWTP dispatch handlers, Restlet (client & server), Piriti on the client and Gson on the server. For me this is the architecture which fits best, as I'm already using Restlet on the server side. IMHO Restlet has some advantages over plain RequestBuilder (see below). It would be nice to have the same code / framework for the JSON encoding / decoding, but as you already noticed Gson is not available for GWT. 

AutoBean vs. Piriti:
The AutoBean API looks very promising. It's part of GWT and will become the standard for JSON encoding / decoding. It might take one or two minor versions until it becomes more stable / usable. Piriti on the other hand is more flexible. You can fine tune which data to map (JSONPath support). Although I didn't try - it should be no problem to replace Piriti in the architecture described in alternative one. So you'll end up with GWTP dispatch handlers, Restlet (client & server) and AutoBean (client & server).

RequestBuilder vs. Restlet:
I prefer to use Restlet over RequestBuilder because it's closer to REST:
  - Support for content negotiation
  - Better error / exception handling
  - Better support for HTTP methods
  - Piriti supports Restlet

Automatic action handler:
I'd love to generate all the boilerplate for each client-server call. Although I wrote an abstract base class for my restful action handlers (http://code.google.com/p/tire-d8/source/browse/trunk/app/src/main/java/name/pehl/tire/client/dispatch/AbstractRestletClientActionHandler.java) to reduce the necessary code, I still have to create three artifacts and register the custom action handler. 

UrlBuilder:
Actually the UrlBuilder class from Piritis Restlet module has no dependency to Restlet or Piriti. I don't know whther it's generic enough to be included into Guava, but it could be part of GWTP. What do you think?

- Harald

Christian Goudreau

unread,
Dec 13, 2010, 10:45:22 AM12/13/10
to gwt-pl...@googlegroups.com
I'd love to generate all the boilerplate for each client-server call
Well, since dispatch use Guice filter, the limitation here is that every permutation of generics must be bound. I think you could get around that limitation by binding every permutation with type literal. That way you won't have to create three classes, but you'll still have to bind every possibility with bindHander.

I didn't tested this, but I'm sure it's possible. I should give it a try and see what I'm missing.

Cheers, 
--
Christian Goudreau

Philippe Beaudoin

unread,
Dec 13, 2010, 11:53:38 AM12/13/10
to gwt-pl...@googlegroups.com
On Mon, Dec 13, 2010 at 7:02 AM, Harald Pehl <haral...@googlemail.com> wrote:
> UrlBuilder:
> Actually the UrlBuilder class from Piritis Restlet module has no dependency
> to Restlet or Piriti. I don't know whther it's generic enough to be included
> into Guava, but it could be part of GWTP. What do you think?

Can you send a link to that class and some doc?

Cheers,

Philippe

marius andreiana

unread,
Dec 13, 2010, 12:58:30 PM12/13/10
to GWTP
On Dec 13, 6:53 pm, Philippe Beaudoin <philippe.beaud...@gmail.com>
wrote:
> On Mon, Dec 13, 2010 at 7:02 AM, Harald Pehl <harald.p...@googlemail.com> wrote:
> > UrlBuilder:
> > Actually the UrlBuilder class from Piritis Restlet module has no dependency
> > to Restlet or Piriti. I don't know whther it's generic enough to be included
> > into Guava, but it could be part of GWTP. What do you think?
>
> Can you send a link to that class and some doc?
http://code.google.com/p/piriti/source/browse/trunk/restlet/src/main/java/name/pehl/piriti/restlet/client/UrlBuilder.java

I was proposing guava rather than gwtp, to avoid introducing a
dependency of piriti-restlet to gwtp.

Harald Pehl

unread,
Dec 13, 2010, 3:42:56 PM12/13/10
to gwt-pl...@googlegroups.com

marius andreiana

unread,
Dec 17, 2010, 3:04:49 AM12/17/10
to GWTP
What do you think about having something like @GenRESTDispatch which,
starting from a regular @GenDispatch class, would generate not only
the Action/Result, but also the required models to send and receive
JSON REST data? Maybe using AutoBean rather than piriti, to minimize
external library dependencies.

I'm not sure how it would handle embedded classes.

Harald Pehl

unread,
Dec 17, 2010, 5:41:59 AM12/17/10
to gwt-pl...@googlegroups.com
Sounds interesting, but I'm not sure whether it will bring any benefit. It might work for simple models, but as soon as you have a more complex class hierarchy I'm afraid it won't work. IMHO generating the models will reduce flexibility. The models might be used for different mappings / resources. I'm not sure how this could be handled using code generation.

In my current aplication I'm using the @GenDispatch annotation to generate the action and result classes. I have an abstract base class which does the REST stuff and implements ClientActionHandler. For a new use case I have to overwrite two methods and register the action handler against DefaultClientActionHandlerRegistry. So besides the models I have to create two classes and add the registration code, which is ok for me.

JHarvey

unread,
Dec 17, 2010, 5:38:02 PM12/17/10
to GWTP
It would be most productive for me to start with a very simple,
absolutely bare bones but complete example before moving to one with
the full functions being illustrated. I find when I am trying to plow
through the examples that are mentioned that I have two learning
curves: a) still trying to learn all the points of GWTP and b) trying
to see the functionality the author is adding for his own purposes on
top of the GWTP code.

Maybe this just begs for someone to do a really detailed walkthough of
a working sample that does one and only one simple thing.

marius andreiana

unread,
Dec 18, 2010, 6:08:09 AM12/18/10
to GWTP
On Dec 17, 12:41 pm, Harald Pehl <harald.p...@googlemail.com> wrote:
> Sounds interesting, but I'm not sure whether it will bring any benefit. It
> might work for simple models, but as soon as you have a more complex class
> hierarchy I'm afraid it won't work. IMHO generating the models will reduce
> flexibility. The models might be used for different mappings / resources.
> I'm not sure how this could be handled using code generation.
Good point.

> In my current aplication I'm using the @GenDispatch annotation to generate
> the action and result classes. I have an abstract base class which does the
> REST stuff and implements ClientActionHandler. For a new use case I have to
> overwrite two methods and register the action handler against
> DefaultClientActionHandlerRegistry. So besides the models I have to create
> two classes and add the registration code, which is ok for me.
>
> What do you think?
It does look good. Just to make sure I've understood everything, I've
implemented a working sample and described it here
http://code.google.com/p/gwt-gae-book/wiki/GWTREST


How about making the model writing easier by implementing in Piriti an
annotation on the class name, which would auto-generate the two Reader
and Writer interfaces?
e.g.
@RESTModel
public class Activity extends DescriptiveModel
would generate ActivityReader.java and ActivityWriter.java

Or even better, somehow remove the need from having these interfaces
and let piriti/piriti-restlet handle this completely?


PS: it would help to have a description on tire-d8 homepage on what
each of the app/model/rest/... projects are doing and dependencies
between them. e.g. model seems to be just server-side model, not gwt.
Looks like there are no deps between client & server side, which is
nice as it allows replacing each of them with other project, as long
as they are using REST.
PPS: I don't understand what exactly piriti-
restlet.JsonModel(s)Response does, as isn't used in tire-d8.

Thanks Harald

marius andreiana

unread,
Dec 18, 2010, 6:09:15 AM12/18/10
to GWTP
I'll do one around Christmas, after we clarify here what's the best
approach. It will be part of http://code.google.com/p/gwt-gae-book/


Harald Pehl

unread,
Dec 20, 2010, 4:45:40 AM12/20/10
to gwt-pl...@googlegroups.com
It does look good. Just to make sure I've understood everything, I've
implemented a working sample and described it here
http://code.google.com/p/gwt-gae-book/wiki/GWTREST
Looks very complete. The GWTP dispatch / GWT Restlet / Piriti approach is quite similar to what I'm using in TiRe. RequestBuilder / Piriti is IMO a reasonable alternative if you don't want the extra dependeny for Restlet. By the way: you don't have to have the JsonReader<T> interfaces in your model. In TiRe I made them first class interfaces which are injected by GIN. You just have to make sure that you bind them eagerly so that Piritis internal model registry is setup correclty: http://code.google.com/p/tire-d8/source/browse/trunk/app/src/main/java/name/pehl/tire/client/gin/TireModule.java.


How about making the model writing easier by implementing in Piriti an
annotation on the class name, which would auto-generate the two Reader
and Writer interfaces?
e.g.
        @RESTModel
        public class Activity extends DescriptiveModel
would generate ActivityReader.java and ActivityWriter.java

Or even better, somehow remove the need from having these interfaces
and let piriti/piriti-restlet handle this completely?
Good idea. I created an issue in Piriti to track this. Feel free to comment: http://code.google.com/p/piriti/issues/detail?id=22. I'm not quite sure if we can generate the JsonReader<T> and JsonWriter<T> interfaces as these interfaces trigger the deferred binding.


PS: it would help to have a description on tire-d8 homepage on what
each of the app/model/rest/... projects are doing and dependencies
between them. e.g. model seems to be just server-side model, not gwt.
Looks like there are no deps between client & server side, which is
nice as it allows replacing each of them with other project, as long
as they are using REST.
That's right! Documentation always lags behind :-( I'll try to add some wiki pages for TiRe asap. For the meantime, you're right the server side model is 99% independent from the client side model. The 1% are two enums which are used on both sides. The server side model is used by the Objectify-DAOs for persistence and the resources to generate JSON representations using Gson. On the client the JSON representations are turned by Piriti into client side models. The server and client side models are quite similar, but generally the server side models are richer. 
 

PPS: I don't understand what exactly piriti-
restlet.JsonModel(s)Response does, as isn't used in tire-d8.
JsonModelResponse<T> and JsonModelsResponse<T> are convinience classes to simplifiy the mapping code. All they do is to read the resource and extract the model(s):

PiritiJsonRepresentation<T> representation = new PiritiJsonRepresentation<T>(jsonReader, response.getEntity());
T model = representation.getModel();
onSuccess(model, request, response);

The reason I didn't used them in TiRe is that I have one abstract action handler and the convinince classes are designed to read either a single model or a list of models.


Thanks Harald
 You're welcome


- Harald
Reply all
Reply to author
Forward
0 new messages