> He suggests a command pattern implementation for RPC calling (see
> slides 21-25) they are using in Wave.
Ray,
If you're reading this, can you tell us if the full code for your
contact
manager is available anywhere? Also, the second of the "Contact
DIsplay UI"
slides has the line
1) Too many parameters. It's just not pretty
2) I have to parameterize the RPCServiceAsync at the class level,
whereas I would like to parameterize at the method level. This is a
constraint of the compiler.
3) All my server-side code actually resides on the client side,
because of the aggressive nature of the GWT compiler. I would add my
voice again asking for a simple annotation or annotations like
on a class: @GWTIgnoreReference(ServerSideClass.class)
and/or a method: @GWTIgnoreMethod
I think there are many justifiable use cases for this type of thing,
and I can't think of any way it would decrease user experience. Does
anyone know if this is a planned feature? Any comments/suggestions on
how to remediate the problems above that I don't know of? Ray Ryan,
are you listening?
Thanks,
On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > He suggests acommandpatternimplementation for RPC calling (see
> > slides 21-25) they are using in Wave.
> Ray,
> If you're reading this, can you tell us if the full code for your
> contact
> manager is available anywhere? Also, the second of the "Contact
> DIsplay UI"
> slides has the line
I think your implementation is over-complicated. On the client side,
just stick to two basic interfaces (and concrete implementations there-
of) - Action and Result (I'm using 'Result' rather than 'Response'
because that is often used in HTTP-related APIs), or in your API,
IProcedure and IReturn. The IAttributes, IRemoteProcedure and other
interfaces are unnecessary.
Then, on the server side, I've got 'ActionHandler' classes, which look
something like this:
public interface ActionHandler<A extends Action<R>, R extends Result>
{
public Class<A> getActionType();
public R execute( A action ) throws Exception;
}
You then register your various ActionHandler instances with your
'RPCService' and it just matches up the action passed in with the
appropriate action handler, calls execute and you're off to the races.
Sorry about the incomplete example - the code itself is tied up in the
app I'm using this in at the moment. I hope to make it a bit more
general down the track.
David
On Jun 30, 8:05 pm, ClusterCougar <nwwe...@gmail.com> wrote:
> 1) Too many parameters. It's just not pretty
> 2) I have to parameterize the RPCServiceAsync at the class level,
> whereas I would like to parameterize at the method level. This is a
> constraint of the compiler.
> 3) All my server-side code actually resides on the client side,
> because of the aggressive nature of the GWT compiler. I would add my
> voice again asking for a simple annotation or annotations like
> on a class: @GWTIgnoreReference(ServerSideClass.class)
> and/or a method: @GWTIgnoreMethod
> I think there are many justifiable use cases for this type of thing,
> and I can't think of any way it would decrease user experience. Does
> anyone know if this is a planned feature? Any comments/suggestions on
> how to remediate the problems above that I don't know of? Ray Ryan,
> are you listening?
> Thanks,
> On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > On Jun 25, 5:12 pm, Herme Garcia <hgar...@peoplecall.com> wrote:
> > > Hi,
> > > After listening carefully Google IO's session from Ray Ryan about
> > > "Best PracticesFor Architecting Your GWT App" :
> > > He suggests acommandpatternimplementation for RPC calling (see
> > > slides 21-25) they are using in Wave.
> > Ray,
> > If you're reading this, can you tell us if the full code for your
> > contact
> > manager is available anywhere? Also, the second of the "Contact
> > DIsplay UI"
> > slides has the line
Thanks David. That looks like a much better solution. The only reason
I did all those generics was because I was still trying to wrap my
head around the problem. Based on this, I've come up with some ideas
I'm going to try to implement. How do you register your
ActionHandlers?
On Jul 3, 8:55 am, David Peterson <da...@randombits.org> wrote:
> I think your implementation is over-complicated. On the client side,
> just stick to two basic interfaces (and concrete implementations there-
> of) - Action and Result (I'm using 'Result' rather than 'Response'
> because that is often used in HTTP-related APIs), or in your API,
> IProcedure and IReturn. The IAttributes, IRemoteProcedure and other
> interfaces are unnecessary.
> Then, on the server side, I've got 'ActionHandler' classes, which look
> something like this:
> public interface ActionHandler<A extends Action<R>, R extends Result>
> {
> public Class<A> getActionType();
> public R execute( A action ) throws Exception;
> }
> You then register your various ActionHandler instances with your
> 'RPCService' and it just matches up the action passed in with the
> appropriate action handler, calls execute and you're off to the races.
> Sorry about the incomplete example - the code itself is tied up in the
> app I'm using this in at the moment. I hope to make it a bit more
> general down the track.
> David
> On Jun 30, 8:05 pm, ClusterCougar <nwwe...@gmail.com> wrote:
> > I thought I posted this last night, but I don't see it. Apologies if
> > this is a dupe.
> > I've tried to implement thecommandpatternusing generics, but have
> > some hangups. You can see my code at
> > 1) Too many parameters. It's just not pretty
> > 2) I have to parameterize the RPCServiceAsync at the class level,
> > whereas I would like to parameterize at the method level. This is a
> > constraint of the compiler.
> > 3) All my server-side code actually resides on the client side,
> > because of the aggressive nature of the GWT compiler. I would add my
> > voice again asking for a simple annotation or annotations like
> > on a class: @GWTIgnoreReference(ServerSideClass.class)
> > and/or a method: @GWTIgnoreMethod
> > I think there are many justifiable use cases for this type of thing,
> > and I can't think of any way it would decrease user experience. Does
> > anyone know if this is a planned feature? Any comments/suggestions on
> > how to remediate the problems above that I don't know of? Ray Ryan,
> > are you listening?
> > Thanks,
> > On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > > On Jun 25, 5:12 pm, Herme Garcia <hgar...@peoplecall.com> wrote:
> > > > Hi,
> > > > After listening carefully Google IO's session from Ray Ryan about
> > > > "Best PracticesFor Architecting Your GWT App" :
> > > > He suggests acommandpatternimplementation for RPC calling (see
> > > > slides 21-25) they are using in Wave.
> > > Ray,
> > > If you're reading this, can you tell us if the full code for your
> > > contact
> > > manager is available anywhere? Also, the second of the "Contact
> > > DIsplay UI"
> > > slides has the line
There are a couple of ways to go about it, and I'm not 100% happy with
my current solution as a 'best practice'. It's a bit convoluted,
really. Current I'm using Guice on the server-side, so I bind them to
'ActionHandler.class', and then a post-config step pulls all
ActionHandler bindings and registers them to my ActionHandlerRegistry.
A simpler way would be to have an eager singleton which is provided
the actionHandlerRegistry via injection and just adds whatever
handlers you want to it.
David
On Jul 4, 8:06 am, ClusterCougar <nwwe...@gmail.com> wrote:
> Thanks David. That looks like a much better solution. The only reason
> I did all those generics was because I was still trying to wrap my
> head around the problem. Based on this, I've come up with some ideas
> I'm going to try to implement. How do you register your
> ActionHandlers?
> On Jul 3, 8:55 am, David Peterson <da...@randombits.org> wrote:
> > Hey ClusterCougar,
> > I think your implementation is over-complicated. On the client side,
> > just stick to two basic interfaces (and concrete implementations there-
> > of) - Action and Result (I'm using 'Result' rather than 'Response'
> > because that is often used in HTTP-related APIs), or in your API,
> > IProcedure and IReturn. The IAttributes, IRemoteProcedure and other
> > interfaces are unnecessary.
> > Then, on the server side, I've got 'ActionHandler' classes, which look
> > something like this:
> > public interface ActionHandler<A extends Action<R>, R extends Result>
> > {
> > public Class<A> getActionType();
> > public R execute( A action ) throws Exception;
> > }
> > You then register your various ActionHandler instances with your
> > 'RPCService' and it just matches up the action passed in with the
> > appropriate action handler, calls execute and you're off to the races.
> > Sorry about the incomplete example - the code itself is tied up in the
> > app I'm using this in at the moment. I hope to make it a bit more
> > general down the track.
> > David
> > On Jun 30, 8:05 pm, ClusterCougar <nwwe...@gmail.com> wrote:
> > > I thought I posted this last night, but I don't see it. Apologies if
> > > this is a dupe.
> > > I've tried to implement thecommandpatternusing generics, but have
> > > some hangups. You can see my code at
> > > 1) Too many parameters. It's just not pretty
> > > 2) I have to parameterize the RPCServiceAsync at the class level,
> > > whereas I would like to parameterize at the method level. This is a
> > > constraint of the compiler.
> > > 3) All my server-side code actually resides on the client side,
> > > because of the aggressive nature of the GWT compiler. I would add my
> > > voice again asking for a simple annotation or annotations like
> > > on a class: @GWTIgnoreReference(ServerSideClass.class)
> > > and/or a method: @GWTIgnoreMethod
> > > I think there are many justifiable use cases for this type of thing,
> > > and I can't think of any way it would decrease user experience. Does
> > > anyone know if this is a planned feature? Any comments/suggestions on
> > > how to remediate the problems above that I don't know of? Ray Ryan,
> > > are you listening?
> > > Thanks,
> > > On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > > > On Jun 25, 5:12 pm, Herme Garcia <hgar...@peoplecall.com> wrote:
> > > > > Hi,
> > > > > After listening carefully Google IO's session from Ray Ryan about
> > > > > "Best PracticesFor Architecting Your GWT App" :
> > > > > He suggests acommandpatternimplementation for RPC calling (see
> > > > > slides 21-25) they are using in Wave.
> > > > Ray,
> > > > If you're reading this, can you tell us if the full code for your
> > > > contact
> > > > manager is available anywhere? Also, the second of the "Contact
> > > > DIsplay UI"
> > > > slides has the line
Just a couple of other comments on this general topic.
1. Yes, it's one-class-per RPC method. This is actually a good thing,
since it lets you do item 2, which is:
2. You can add 'undo' to your actions. This is particularly handy if
you build your Action classes using item 3:
3. You can have one action which executes multiple other items. This
means you're using the command pattern on the server side too, not
just from the client side.
When you add them all together, most of your actual functionality is
encapsulated in command/action classes. I use the same service
implementation on the server side as the client side, so there is
really just one shared service now (I call it 'Dispatch') rather than
having various services for different application functions.
But for me, the biggest win is 'undo' - it's essentially like having
transactions for Java code, not just database code. Not quite as
bullet-proof, since some actions can't actually be undone, but a big
step in that direction.
I will see if I can get the code abstracted enough from my app to post
it publicly.
> Just a couple of other comments on this general topic.
> 1. Yes, it's one-class-per RPC method. This is actually a good thing,
> since it lets you do item 2, which is:
> 2. You can add 'undo' to your actions. This is particularly handy if
> you build your Action classes using item 3:
> 3. You can have one action which executes multiple other items. This
> means you're using thecommandpatternon the server side too, not
> just from the client side.
> When you add them all together, most of your actual functionality is
> encapsulated incommand/action classes. I use the same service
> implementation on the server side as the client side, so there is
> really just one shared service now (I call it 'Dispatch') rather than
> having various services for different application functions.
> But for me, the biggest win is 'undo' - it's essentially like having
> transactions for Java code, not just database code. Not quite as
> bullet-proof, since some actions can't actually be undone, but a big
> step in that direction.
> I will see if I can get the code abstracted enough from my app to post
> it publicly.
Thanks both to David and ClusterCougar for your efforts!
I've also been struggeling with this for a while now and got something
similar to the command model Ray Ryan described it in the talk.
Your version of it David, with the undo-functionality, sounds very
interessting though. I'd be very interested to see some version of it
if you have the time.
Thanks!
On Jul 4, 3:51 am, David Peterson <da...@randombits.org> wrote:
> Just a couple of other comments on this general topic.
> 1. Yes, it's one-class-per RPC method. This is actually a good thing,
> since it lets you do item 2, which is:
> 2. You can add 'undo' to your actions. This is particularly handy if
> you build your Action classes using item 3:
> 3. You can have one action which executes multiple other items. This
> means you're using the command pattern on the server side too, not
> just from the client side.
> When you add them all together, most of your actual functionality is
> encapsulated in command/action classes. I use the same service
> implementation on the server side as the client side, so there is
> really just one shared service now (I call it 'Dispatch') rather than
> having various services for different application functions.
> But for me, the biggest win is 'undo' - it's essentially like having
> transactions for Java code, not just database code. Not quite as
> bullet-proof, since some actions can't actually be undone, but a big
> step in that direction.
> I will see if I can get the code abstracted enough from my app to post
> it publicly.
The Apache Shindig project (reference implementation of OpenSocial)
provides another approach for registering ActionHandlers. The Shindig
OpenSocial API code uses a HandlerDispatcher to dispatch Action
handling (as opposed to using the Servlet to do this directly). For
application specific registration, you'd write an Application specific
HandlerDispatcher and inject that Dispatcher into your RPC Servlet.
Your RPC Servlet would then do any initial processing on RPC calls,
and then retrieve the ActionHandler from the dispatcher and handle the
request. In this case, as you build new Actions you simply add a new
Handler (or update a previous one to Handle the new action, as
desired).
I haven't tried implementing this same approach, but I don't see any
issues with it at this point. Note that Shindig goes a bit farther as
their Handlers pass of most processes to a Service Provider Interface
that can be replaced with concrete implementation.
> There are a couple of ways to go about it, and I'm not 100% happy with
> my current solution as a 'best practice'. It's a bit convoluted,
> really. Current I'm using Guice on the server-side, so I bind them to
> 'ActionHandler.class', and then a post-config step pulls all
> ActionHandler bindings and registers them to my ActionHandlerRegistry.
> A simpler way would be to have an eager singleton which is provided
> the actionHandlerRegistry via injection and just adds whatever
> handlers you want to it.
> David
> On Jul 4, 8:06 am, ClusterCougar <nwwe...@gmail.com> wrote:
> > Thanks David. That looks like a much better solution. The only reason
> > I did all those generics was because I was still trying to wrap my
> > head around the problem. Based on this, I've come up with some ideas
> > I'm going to try to implement. How do you register your
> > ActionHandlers?
> > On Jul 3, 8:55 am, David Peterson <da...@randombits.org> wrote:
> > > Hey ClusterCougar,
> > > I think your implementation is over-complicated. On the client side,
> > > just stick to two basic interfaces (and concrete implementations there-
> > > of) - Action and Result (I'm using 'Result' rather than 'Response'
> > > because that is often used in HTTP-related APIs), or in your API,
> > > IProcedure and IReturn. The IAttributes, IRemoteProcedure and other
> > > interfaces are unnecessary.
> > > Then, on the server side, I've got 'ActionHandler' classes, which look
> > > something like this:
> > > public interface ActionHandler<A extends Action<R>, R extends Result>
> > > {
> > > public Class<A> getActionType();
> > > public R execute( A action ) throws Exception;
> > > }
> > > You then register your various ActionHandler instances with your
> > > 'RPCService' and it just matches up the action passed in with the
> > > appropriate action handler, calls execute and you're off to the races.
> > > Sorry about the incomplete example - the code itself is tied up in the
> > > app I'm using this in at the moment. I hope to make it a bit more
> > > general down the track.
> > > David
> > > On Jun 30, 8:05 pm, ClusterCougar <nwwe...@gmail.com> wrote:
> > > > I thought I posted this last night, but I don't see it. Apologies if
> > > > this is a dupe.
> > > > I've tried to implement thecommandpatternusing generics, but have
> > > > some hangups. You can see my code at
> > > > 1) Too many parameters. It's just not pretty
> > > > 2) I have to parameterize the RPCServiceAsync at the class level,
> > > > whereas I would like to parameterize at the method level. This is a
> > > > constraint of the compiler.
> > > > 3) All my server-side code actually resides on the client side,
> > > > because of the aggressive nature of the GWT compiler. I would add my
> > > > voice again asking for a simple annotation or annotations like
> > > > on a class: @GWTIgnoreReference(ServerSideClass.class)
> > > > and/or a method: @GWTIgnoreMethod
> > > > I think there are many justifiable use cases for this type of thing,
> > > > and I can't think of any way it would decrease user experience. Does
> > > > anyone know if this is a planned feature? Any comments/suggestions on
> > > > how to remediate the problems above that I don't know of? Ray Ryan,
> > > > are you listening?
> > > > Thanks,
> > > > On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > > > > On Jun 25, 5:12 pm, Herme Garcia <hgar...@peoplecall.com> wrote:
> > > > > > Hi,
> > > > > > After listening carefully Google IO's session from Ray Ryan about
> > > > > > "Best PracticesFor Architecting Your GWT App" :
> > > > > > He suggests acommandpatternimplementation for RPC calling (see
> > > > > > slides 21-25) they are using in Wave.
> > > > > Ray,
> > > > > If you're reading this, can you tell us if the full code for your
> > > > > contact
> > > > > manager is available anywhere? Also, the second of the "Contact
> > > > > DIsplay UI"
> > > > > slides has the line
Ok, just relooked and apparently the approach I described above was
part of the 0.8 Shindig release, not the current 0.9. The pattern is
still similar, but the implementation is a bit more confusing if you
look at the Shindig code directly. Other than the references above to
the Shindig source locations, the approach for the most part still
stands (the code is just built with more complex dependency
injection).
Respectfully,
Jason
On Jul 4, 7:42 am, "Jason A. Beranek" <jason.bera...@gmail.com> wrote:
> The Apache Shindig project (reference implementation of OpenSocial)
> provides another approach for registering ActionHandlers. The Shindig
> OpenSocial API code uses a HandlerDispatcher to dispatch Action
> handling (as opposed to using the Servlet to do this directly). For
> application specific registration, you'd write an Application specific
> HandlerDispatcher and inject that Dispatcher into your RPC Servlet.
> Your RPC Servlet would then do any initial processing on RPC calls,
> and then retrieve the ActionHandler from the dispatcher and handle the
> request. In this case, as you build new Actions you simply add a new
> Handler (or update a previous one to Handle the new action, as
> desired).
> I haven't tried implementing this same approach, but I don't see any
> issues with it at this point. Note that Shindig goes a bit farther as
> their Handlers pass of most processes to a Service Provider Interface
> that can be replaced with concrete implementation.
> On Jul 3, 8:18 pm, David Peterson <da...@randombits.org> wrote:
> > There are a couple of ways to go about it, and I'm not 100% happy with
> > my current solution as a 'best practice'. It's a bit convoluted,
> > really. Current I'm using Guice on the server-side, so I bind them to
> > 'ActionHandler.class', and then a post-config step pulls all
> > ActionHandler bindings and registers them to my ActionHandlerRegistry.
> > A simpler way would be to have an eager singleton which is provided
> > the actionHandlerRegistry via injection and just adds whatever
> > handlers you want to it.
> > David
> > On Jul 4, 8:06 am, ClusterCougar <nwwe...@gmail.com> wrote:
> > > Thanks David. That looks like a much better solution. The only reason
> > > I did all those generics was because I was still trying to wrap my
> > > head around the problem. Based on this, I've come up with some ideas
> > > I'm going to try to implement. How do you register your
> > > ActionHandlers?
> > > On Jul 3, 8:55 am, David Peterson <da...@randombits.org> wrote:
> > > > Hey ClusterCougar,
> > > > I think your implementation is over-complicated. On the client side,
> > > > just stick to two basic interfaces (and concrete implementations there-
> > > > of) - Action and Result (I'm using 'Result' rather than 'Response'
> > > > because that is often used in HTTP-related APIs), or in your API,
> > > > IProcedure and IReturn. The IAttributes, IRemoteProcedure and other
> > > > interfaces are unnecessary.
> > > > Then, on the server side, I've got 'ActionHandler' classes, which look
> > > > something like this:
> > > > public interface ActionHandler<A extends Action<R>, R extends Result>
> > > > {
> > > > public Class<A> getActionType();
> > > > public R execute( A action ) throws Exception;
> > > > }
> > > > You then register your various ActionHandler instances with your
> > > > 'RPCService' and it just matches up the action passed in with the
> > > > appropriate action handler, calls execute and you're off to the races.
> > > > Sorry about the incomplete example - the code itself is tied up in the
> > > > app I'm using this in at the moment. I hope to make it a bit more
> > > > general down the track.
> > > > David
> > > > On Jun 30, 8:05 pm, ClusterCougar <nwwe...@gmail.com> wrote:
> > > > > I thought I posted this last night, but I don't see it. Apologies if
> > > > > this is a dupe.
> > > > > I've tried to implement thecommandpatternusing generics, but have
> > > > > some hangups. You can see my code at
> > > > > 1) Too many parameters. It's just not pretty
> > > > > 2) I have to parameterize the RPCServiceAsync at the class level,
> > > > > whereas I would like to parameterize at the method level. This is a
> > > > > constraint of the compiler.
> > > > > 3) All my server-side code actually resides on the client side,
> > > > > because of the aggressive nature of the GWT compiler. I would add my
> > > > > voice again asking for a simple annotation or annotations like
> > > > > on a class: @GWTIgnoreReference(ServerSideClass.class)
> > > > > and/or a method: @GWTIgnoreMethod
> > > > > I think there are many justifiable use cases for this type of thing,
> > > > > and I can't think of any way it would decrease user experience. Does
> > > > > anyone know if this is a planned feature? Any comments/suggestions on
> > > > > how to remediate the problems above that I don't know of? Ray Ryan,
> > > > > are you listening?
> > > > > Thanks,
> > > > > On Jun 25, 4:07 pm, Eric <erjab...@gmail.com> wrote:
> > > > > > On Jun 25, 5:12 pm, Herme Garcia <hgar...@peoplecall.com> wrote:
> > > > > > > Hi,
> > > > > > > After listening carefully Google IO's session from Ray Ryan about
> > > > > > > "Best PracticesFor Architecting Your GWT App" :
> > > > > > > He suggests acommandpatternimplementation for RPC calling (see
> > > > > > > slides 21-25) they are using in Wave.
> > > > > > Ray,
> > > > > > If you're reading this, can you tell us if the full code for your
> > > > > > contact
> > > > > > manager is available anywhere? Also, the second of the "Contact
> > > > > > DIsplay UI"
> > > > > > slides has the line
Jason: I'll admit I was unable to figure out exactly what Shindig's
approach is, exactly, unfortunately. However there is definitely more
than one way to skin this cat. My current implementation an Action, a
Result and a Handler for each operation. This does result in some
class proliferation, but has the upside of having everything nicely
self-contained.
In my implementation, I actually have a 'Dispatch' class which can be
injected directly, and a separate DispatchServiceServlet which is also
injected the same Dispatch instance and provides access from GWT/RPC.
To hold you over while I get the code sorted, here is a simple example
of what an action/result/handler looks like:
It's just a concrete implementation of ActionHandler. Essentially,
each Action/Result has a single ActionHandler that does the actual
execution on the server side.
getActionType() returns the concrete Action subclass that the handler
supports. For example, a 'Get User' operation might look like this:
public class GetUser implements Action<GetUserResult> {
private String name;
// For serialization
GetUser() {}
public GetUser( String name ) {
this.name = name;
}
public String getName() {
return name;
}
}
public class GetUserResult implements Result {
private User user;
// Serialization
GetUserResult() {}
public GetUserResult( User user ) {
this.user = user;
}
public User getUser() {
return user;
}
}
// This class is server-side only
public GetUserHandler implements ActionHandler<GetUser, GetUserResult>
{
private final UserDAO dao;
@Inject
public GetUserHandler( UserDAO dao ) {
this.dao = dao;
}
public Class<GetUser> getActionType() {
return GetUser.class;
}
public GetUserResult execute( GetUser action ) throws Exception {
return new GetUserResult( dao.getUser( action.getName() ) );
}
}
A very simple example, and the actual 'getting' code is wrapped in the
DAO in this case. It could equally be coded directly in, or hooking up
to a non-DB service. Depends how you want to implement it.
> Jason: I'll admit I was unable to figure out exactly what Shindig's
> approach is, exactly, unfortunately. However there is definitely more
> than one way to skin this cat. My current implementation an Action, a
> Result and a Handler for each operation. This does result in some
> class proliferation, but has the upside of having everything nicely
> self-contained.
> In my implementation, I actually have a 'Dispatch' class which can be
> injected directly, and a separate DispatchServiceServlet which is also
> injected the same Dispatch instance and provides access from GWT/RPC.
> To hold you over while I get the code sorted, here is a simple example
> of what an action/result/handler looks like:
> It's just a concrete implementation of ActionHandler. Essentially,
> each Action/Result has a single ActionHandler that does the actual
> execution on the server side.
> getActionType() returns the concrete Action subclass that the handler
> supports. For example, a 'Get User' operation might look like this:
> public class GetUser implements Action<GetUserResult> {
> private String name;
> // For serialization
> GetUser() {}
> public GetUser( String name ) {
> this.name = name;
> }
> public String getName() {
> return name;
> }
> }
> public class GetUserResult implements Result {
> private User user;
> // Serialization
> GetUserResult() {}
> public GetUserResult( User user ) {
> this.user = user;
> }
> public User getUser() {
> return user;
> }
> }
> // This class is server-side only
> public GetUserHandler implements ActionHandler<GetUser, GetUserResult>
> {
> private final UserDAO dao;
> @Inject
> public GetUserHandler( UserDAO dao ) {
> this.dao = dao;
> }
> public Class<GetUser> getActionType() {
> return GetUser.class;
> }
> public GetUserResult execute( GetUser action ) throws Exception {
> return new GetUserResult( dao.getUser( action.getName() ) );
> }
> }
> A very simple example, and the actual 'getting' code is wrapped in the
> DAO in this case. It could equally be coded directly in, or hooking up
> to a non-DB service. Depends how you want to implement it.
I updated my project to only use the two interfaces as suggested by
David. Instead of using actionhandlers and registering them, I created
an annotation for the IRemoteProcedureCall implementations that
contains the canonical class name of the IProcedure that is to be run
on the server.
I'm very open to suggestions. Let me know what you think :)
> On 4 jul, 15:49, David Peterson <da...@randombits.org> wrote:
> > Jason: I'll admit I was unable to figure out exactly what Shindig's
> > approach is, exactly, unfortunately. However there is definitely more
> > than one way to skin this cat. My current implementation an Action, a
> > Result and a Handler for each operation. This does result in some
> > class proliferation, but has the upside of having everything nicely
> > self-contained.
> > In my implementation, I actually have a 'Dispatch' class which can be
> > injected directly, and a separate DispatchServiceServlet which is also
> > injected the same Dispatch instance and provides access from GWT/RPC.
> > To hold you over while I get the code sorted, here is a simple example
> > of what an action/result/handler looks like:
> > It's just a concrete implementation of ActionHandler. Essentially,
> > each Action/Result has a single ActionHandler that does the actual
> > execution on the server side.
> > getActionType() returns the concrete Action subclass that the handler
> > supports. For example, a 'Get User' operation might look like this:
> > public class GetUser implements Action<GetUserResult> {
> > private String name;
> > // For serialization
> > GetUser() {}
> > public GetUser( String name ) {
> > this.name = name;
> > }
> > A very simple example, and the actual 'getting' code is wrapped in the
> > DAO in this case. It could equally be coded directly in, or hooking up
> > to a non-DB service. Depends how you want to implement it.
The original code was working fine, but I haven't had a chance to
test it since it was extracted from the project. It does compile,
although you will currently need Java 1.6 to compile it (even though
it is compiling in 1.5 class/source compatibility mode). There is only
one section of generics-related code that requires 1.6 (you'll figure
it out quickly if you check it out and build with 1.5), so if anyone
can provide a patch I'll be happy to slap it in.
There is also a short example on how to build an action/result/handler
and wire it in via Guice/GIN. That can be had here:
Can someone explain how this is useful? I don't know what a command pattern is. Why should I use command patterns and not the traditional
way? What is the difference? At first look, this seems to be a lot
more complicated, so I'm a little confused.
GWT has some additional quirks that would make an abstracted command pattern nice, but I can see how you could say the added complexity
might detract from those benefits.
On Jul 4, 2:18 pm, martinhansen <martin.hanse...@googlemail.com>
wrote:
> Can someone explain how this is useful? I don't know what a command > pattern is. Why should I use command patterns and not the traditional
> way? What is the difference? At first look, this seems to be a lot
> more complicated, so I'm a little confused.
Yeah, there is some added complexity, however I found myself basically
implementing it in a much more ad-hoc fashion anyway, it's just that
some operations required a 'token' object with multiple parameters, or
returning another token with multiple return values, and some didn't.
This way, it's more consistent, and there is the benefit of undo and
more fine-grained testing.
For this project it was an experiment as much as anything, but from
the experience I generally think there are more benefits than
downsides, even for server-side-only projects. It definitely fits well
with the DI-style of configuration.
Each to their own though - it really is mostly a matter of taste.
On Jul 5, 2:15 am, Nathan Wells <nwwe...@gmail.com> wrote:
> I updated my project to only use the two interfaces as suggested by
> David. Instead of using actionhandlers and registering them, I created
> an annotation for the IRemoteProcedureCall implementations that
> contains the canonical class name of the IProcedure that is to be run
> on the server.
As you say, one of the downsides of linking the handler to the
concrete implementation is that there may be issues with the GWT
compiler. That said, in general it seems to mostly ignore attributes,
so it may not be an issue.
The other downside for me is that it ties the action interface to a
specific implementation. This makes it more difficult to write mocks
for tests, etc. Having them configured purely on the server-side means
you can replace them with whatever you like on in test scenarios. Or,
if you want to provide alternate implementations (eg. JDO vs
Hibernate), you can have both in your app and just switch between them
by changing your DI configuration.
The downside of my method is that you may forget to actually implement
the handler. Of course, this will generally show up pretty quickly
when you try to actually use it. And I guess it's still quite easy to
forget to supply the annotation anyway...
I've read your source code and your example. It is very interesting.
But although it's short and simple, I still don't understand it.
Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
without these technologies?
Does anyone know a really simple example? The example in Ray's sheet
is interesting and simple, but incomplete. Where does the actual
action take place in his example, let's say, querying some contact
details from a remote data base? I think this important part is
missing.
The ContactService defines a method called "execute", but where is
this method implemented? Is it implemented automatically by some
mechanism? If yes, how is it done? Is "execute" the only method in the
interface I ever need, e.g. some kind of place holder?
Any help would be greatly appreciated.
On 5 Jul., 08:17, David Peterson <da...@randombits.org> wrote:
> On Jul 5, 2:15 am, Nathan Wells <nwwe...@gmail.com> wrote:
> > I updated my project to only use the two interfaces as suggested by
> > David. Instead of using actionhandlers and registering them, I created
> > an annotation for the IRemoteProcedureCall implementations that
> > contains the canonical class name of the IProcedure that is to be run
> > on the server.
> As you say, one of the downsides of linking the handler to the
> concrete implementation is that there may be issues with the GWT
> compiler. That said, in general it seems to mostly ignore attributes,
> so it may not be an issue.
> The other downside for me is that it ties the action interface to a
> specific implementation. This makes it more difficult to write mocks
> for tests, etc. Having them configured purely on the server-side means
> you can replace them with whatever you like on in test scenarios. Or,
> if you want to provide alternate implementations (eg. JDO vs
> Hibernate), you can have both in your app and just switch between them
> by changing your DI configuration.
> The downside of my method is that you may forget to actually implement
> the handler. Of course, this will generally show up pretty quickly
> when you try to actually use it. And I guess it's still quite easy to
> forget to supply the annotation anyway...
> I've read your source code and your example. It is very interesting.
> But although it's short and simple, I still don't understand it.
> Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
> without these technologies?
> Does anyone know a really simple example? The example in Ray's sheet
> is interesting and simple, but incomplete. Where does the actual
> action take place in his example, let's say, querying some contact
> details from a remote data base? I think this important part is
> missing.
> The ContactService defines a method called "execute", but where is
> this method implemented? Is it implemented automatically by some
> mechanism? If yes, how is it done? Is "execute" the only method in the
> interface I ever need, e.g. some kind of place holder?
> Any help would be greatly appreciated.
> On 5 Jul., 08:17, David Peterson <da...@randombits.org> wrote:
> > > I updated my project to only use the two interfaces as suggested by
> > > David. Instead of using actionhandlers and registering them, I created
> > > an annotation for the IRemoteProcedureCall implementations that
> > > contains the canonical class name of the IProcedure that is to be run
> > > on the server.
> > As you say, one of the downsides of linking the handler to the
> > concrete implementation is that there may be issues with the GWT
> > compiler. That said, in general it seems to mostly ignore attributes,
> > so it may not be an issue.
> > The other downside for me is that it ties the action interface to a
> > specific implementation. This makes it more difficult to write mocks
> > for tests, etc. Having them configured purely on the server-side means
> > you can replace them with whatever you like on in test scenarios. Or,
> > if you want to provide alternate implementations (eg. JDO vs
> > Hibernate), you can have both in your app and just switch between them
> > by changing your DI configuration.
> > The downside of my method is that you may forget to actually implement
> > the handler. Of course, this will generally show up pretty quickly
> > when you try to actually use it. And I guess it's still quite easy to
> > forget to supply the annotation anyway...
On Jul 5, 6:16 pm, martinhansen <martin.hanse...@googlemail.com>
wrote:
> Hello David,
> I've read your source code and your example. It is very interesting.
> But although it's short and simple, I still don't understand it.
> Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
> without these technologies?
You can use the classes directly, but if you can figure out Guice, it
will save you a fair bit of work in the long run. There is a bit of a
learning curve though. The main things you will need to configure if
you want to do it manually:
Server side:
Provide an instance of 'ActionHandlerRegistry' and 'Dispatch' (you can
use 'DefaultDispatch' for a simple implementation) as a singleton:
public class MyManager {
private static final ActionHandlerRegistry REGISTRY;
private static final Dispatch DISPATCH;
public static Dispatch getDispatch() {
if ( DISPATCH == null ) {
REGISTRY = new DefaultActionHandlerRegistry();
DISPATCH = new DefaultDispatch();
REGISTRY.addHandler( new MyCustomHandler() );
REGISTRY.addHandler( new MyOtherHandler() );
}
return DISPATCH;
}
}
You will also need a subclass of 'DispatchServiceServlet'. Eg:
public class MyDispatchServiceServlet extends DispatchServiceServlet {
public MyDispatchServiceServlet() {
super( MyManager.getDispatch() );
}
}
Then hook that up in the appropriate place for your GWT connection.
On the server side, you just need an instance of 'DispatchAsync'.
Again, 'DefaultDispatchAsync' should do the trick. Eg:
private final static DispatchAsync DISPATCH = new DefaultDispatchAsync
();
Provide an accessor for that to your other classes and off you go.
> I've read your source code and your example. It is very interesting.
> But although it's short and simple, I still don't understand it.
> Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
> without these technologies?
> Does anyone know a really simple example? The example in Ray's sheet
> is interesting and simple, but incomplete. Where does the actual
> action take place in his example, let's say, querying some contact
> details from a remote data base? I think this important part is
> missing.
> The ContactService defines a method called "execute", but where is
> this method implemented? Is it implemented automatically by some
> mechanism? If yes, how is it done? Is "execute" the only method in the
> interface I ever need, e.g. some kind of place holder?
> Any help would be greatly appreciated.
> On 5 Jul., 08:17, David Peterson <da...@randombits.org> wrote:
> > > I updated my project to only use the two interfaces as suggested by
> > > David. Instead of using actionhandlers and registering them, I created
> > > an annotation for the IRemoteProcedureCall implementations that
> > > contains the canonical class name of the IProcedure that is to be run
> > > on the server.
> > As you say, one of the downsides of linking the handler to the
> > concrete implementation is that there may be issues with the GWT
> > compiler. That said, in general it seems to mostly ignore attributes,
> > so it may not be an issue.
> > The other downside for me is that it ties the action interface to a
> > specific implementation. This makes it more difficult to write mocks
> > for tests, etc. Having them configured purely on the server-side means
> > you can replace them with whatever you like on in test scenarios. Or,
> > if you want to provide alternate implementations (eg. JDO vs
> > Hibernate), you can have both in your app and just switch between them
> > by changing your DI configuration.
> > The downside of my method is that you may forget to actually implement
> > the handler. Of course, this will generally show up pretty quickly
> > when you try to actually use it. And I guess it's still quite easy to
> > forget to supply the annotation anyway...
your example is very interesting. I downloaded it and changed it to
work with GWT. But I was not successful. When I run my application,
the compiler complains about my client service interface:
[ERROR] Type 'com.isp.gwtpattern.client.rpc.Response' was not
serializable and has no concrete serializable subtypes
The code is as follows:
@RemoteServiceRelativePath( "buchungServlet" )
public interface BuchungService extends RemoteService {
<T extends Response> T execute(Action<T> action);
}
What am I doing wrong here? My interfaces "Action" and "Response" both
implement IsSerializable.
M
On 5 Jul., 11:55, hgarciag <hgarc...@gmail.com> wrote:
> At the end, you will need to add some more code, but you can see how
> the pattern works (it helped me!)
> Herme
> On Jul 5, 10:16 am, martinhansen <martin.hanse...@googlemail.com>
> wrote:
> > Hello David,
> > I've read your source code and your example. It is very interesting.
> > But although it's short and simple, I still don't understand it.
> > Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
> > without these technologies?
> > Does anyone know a really simple example? The example inRay'ssheet
> > is interesting and simple, but incomplete. Where does the actual
> > action take place in his example, let's say, querying some contact
> > details from a remote data base? I think this important part is
> > missing.
> > The ContactService defines a method called "execute", but where is
> > this method implemented? Is it implemented automatically by some
> > mechanism? If yes, how is it done? Is "execute" the only method in the
> > interface I ever need, e.g. some kind of place holder?
> > Any help would be greatly appreciated.
> > On 5 Jul., 08:17, David Peterson <da...@randombits.org> wrote:
> > > > I updated my project to only use the two interfaces as suggested by
> > > > David. Instead of using actionhandlers and registering them, I created
> > > > an annotation for the IRemoteProcedureCall implementations that
> > > > contains the canonical class name of the IProcedure that is to be run
> > > > on the server.
> > > As you say, one of the downsides of linking the handler to the
> > > concrete implementation is that there may be issues with the GWT
> > > compiler. That said, in general it seems to mostly ignore attributes,
> > > so it may not be an issue.
> > > The other downside for me is that it ties the action interface to a
> > > specific implementation. This makes it more difficult to write mocks
> > > for tests, etc. Having them configured purely on the server-side means
> > > you can replace them with whatever you like on in test scenarios. Or,
> > > if you want to provide alternate implementations (eg. JDO vs
> > > Hibernate), you can have both in your app and just switch between them
> > > by changing your DI configuration.
> > > The downside of my method is that you may forget to actually implement
> > > the handler. Of course, this will generally show up pretty quickly
> > > when you try to actually use it. And I guess it's still quite easy to
> > > forget to supply the annotation anyway...
The Action and Response classes must have an empty default constructor
to be serializable. I've had this error before. Unfortunately, the GWT
compiler error message is anything but helpful in this case. Grrrr.
On 6 Jul., 11:57, martinhansen <martin.hanse...@googlemail.com> wrote:
> your example is very interesting. I downloaded it and changed it to
> work with GWT. But I was not successful. When I run my application,
> the compiler complains about my client service interface:
> [ERROR] Type 'com.isp.gwtpattern.client.rpc.Response' was not
> serializable and has no concrete serializable subtypes
> > > I've read your source code and your example. It is very interesting.
> > > But although it's short and simple, I still don't understand it.
> > > Especially "GIN" and "GUICE" confuses me a lot. Can I use your example
> > > without these technologies?
> > > Does anyone know a really simple example? The example inRay'ssheet
> > > is interesting and simple, but incomplete. Where does the actual
> > > action take place in his example, let's say, querying some contact
> > > details from a remote data base? I think this important part is
> > > missing.
> > > The ContactService defines a method called "execute", but where is
> > > this method implemented? Is it implemented automatically by some
> > > mechanism? If yes, how is it done? Is "execute" the only method in the
> > > interface I ever need, e.g. some kind of place holder?
> > > Any help would be greatly appreciated.
> > > On 5 Jul., 08:17, David Peterson <da...@randombits.org> wrote:
> > > > > I updated my project to only use the two interfaces as suggested by
> > > > > David. Instead of using actionhandlers and registering them, I created
> > > > > an annotation for the IRemoteProcedureCall implementations that
> > > > > contains the canonical class name of the IProcedure that is to be run
> > > > > on the server.
> > > > As you say, one of the downsides of linking the handler to the
> > > > concrete implementation is that there may be issues with the GWT
> > > > compiler. That said, in general it seems to mostly ignore attributes,
> > > > so it may not be an issue.
> > > > The other downside for me is that it ties the action interface to a
> > > > specific implementation. This makes it more difficult to write mocks
> > > > for tests, etc. Having them configured purely on the server-side means
> > > > you can replace them with whatever you like on in test scenarios. Or,
> > > > if you want to provide alternate implementations (eg. JDO vs
> > > > Hibernate), you can have both in your app and just switch between them
> > > > by changing your DI configuration.
> > > > The downside of my method is that you may forget to actually implement
> > > > the handler. Of course, this will generally show up pretty quickly
> > > > when you try to actually use it. And I guess it's still quite easy to
> > > > forget to supply the annotation anyway...