-
The Command Pattern with the Grails GWT Plugin
Posted on August 31st, 2009 39 commentsA talk by Ray Ryan of Google at the 2009 Google IO conference has caused a bit of a buzz in the GWT community. In that talk, Ray recommends several design patterns that will help make your projects more manageable as they grow in size. The particular suggestion I’ll be focusing on in this post concerns using the Command Pattern for server requests.
The idea is to encapsulate the stuff you want the server to do for your client in command or action objects instead of using standard service methods. For example, rather than calling a search() method on a remote service, you have a search object that gets sent to the server and the server returns the corresponding result or response object. By using this pattern, you can effectively implement caching, batching, undo/redo, etc. See Ray’s presentation for a bit more info on this.
One ready-made implementation of the pattern for GWT is the gwt-dispatch library. I considered integrating this into the Grails plugin, but its server-side components weren’t really suitable for a Grails project. Anyway, I wanted to write something myself so I could better understand what the implementation should do. The result is the plugin’s new action framework, which you can test out with an intermediate release of the plugin.
Getting started
Using the framework is simplicity itself. Let’s say you want to implement a search action. You first create the appropriate classes for it by running a new Grails command:
This will create the following files:
grails create-gwt-action org.example.myapp.Search
- src/java/org/example/myapp/client/SearchAction.java
- src/java/org/example/myapp/client/SearchResponse.java
- grails-app/actionHandlers/org/example/myapp/SearchActionHandler.groovy
The action and response classes represent the request and response data respectively. Both of them implement Serializable, so they have to have a default constructor (which can be private) and can only contain other serializable data. Note that they are added to the client sub-package of the package you specify, because they are used on the client was well as the server.
The action handler is an instance of a Grails artifact type added by the plugin. Its role is to process actions and return the appropriate responses. It would typically offload the majority of the work to a standard Grails service that could then be used by other code, such as a REST or web services interface.
The code
Update I have updated the plugin packages in the following examples, so “org.grails.” is now just “grails.” The change was made for the final release of version 0.5.
The action object should contain only the information necessary to complete the request. Remember, it’s a data object and typically won’t have any behaviour. In the case of our search action, we might need a query string and the maximum number of results the search should return:
package org.example.myapp.client; import grails.plugins.gwt.client.Action; public final class SearchAction implements Action<SearchResponse> { private static final long serialVersionUID = 1L; private String query; private SearchAction() {} public SearchAction(String query) { this.query = query; } public String getQuery() { return query; } }Likewise, the response should only contain the data required by the client:
package org.example.myapp.client; import java.util.ArrayList; import java.util.Collections; import java.util.List; import grails.plugins.gwt.client.Response; public class SearchResponse implements Response { private static final long serialVersionUID = 1L; private ArrayList<Long> ids = new ArrayList<Long>(); private SearchResponse() {} public SearchResponse(List<Long> ids) { this.ids.addAll(ids); } public List<Integer> getIds() { return Collections.unmodifiableList(this.ids); } }All very straightforward so far. The final step is to implement the action handler. As I said, this typically offloads the work to a service and in our example we will make use of a search service:
package org.example.myapp import org.example.myapp.client.SearchAction import org.example.myapp.client.SearchResults class SearchActionHandler { SearchService searchService SearchResponse execute(SearchAction action) { def results = searchService.executeSearch(action.query) return new SearchResponse(results) } }As you can see, all the action needs to do is unwrap the action and create the response. Everything else is handled by the search service. We haven’t even needed to expose a service via GWT! That’s all you need to do on the server side, which just leaves the question of how you execute an action from the client.
On the client
The plugin comes with a dedicated GWT RPC service that you can use to dispatch all your actions: GwtActionService. All you have to do in your GWT code is create the service, instantiate your action, and then call the execute() method:
... import grails.plugins.gwt.client.GwtActionService; import grails.plugins.gwt.client.GwtActionServiceAsync; ... protected void doSearch(String query) { GwtActionServiceAsync service = GWT.create(GwtActionService.class); ((ServiceDefTarget) service).setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc"); service.execute(new SearchAction(query), new AsyncCallback<SearchResponse>() { public void onFailure (Throwable caught) { ... } public void onSuccess (GetRecentResponse result) { ... } }); }You could even wrap the action service with another implementation that does caching and/or batching of commands.
If you use Google Gin, you can simplify your code by having the action service injected into the classes that need it. Simply add something like this to your Gin module definition:
... import grails.plugins.gwt.client.GwtActionService; import grails.plugins.gwt.client.GwtActionServiceAsync; public class MainModule extends AbstractGinModule { protected void configure() { ... } @Provides @Singleton GwtActionServiceAsync provideGwtActionService() { GwtActionServiceAsync service = GWT.create(GwtActionService.class); ((ServiceDefTarget) service).setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc"); return service; } }Since GwtActionService is provided by the plugin, you also need to configure your module to inherit from the plugin’s (new) module:
<module> ... <inherits name="grails.plugins.gwt.Grails"/> ... </module>I think this is a really clean approach to GWT RPC that reduces the burden on you as a developer. In particular, you no longer have to implement GWT services because you can create simple action handlers instead. Before I implemented this framework, I found that I was creating specific GWT versions of each service. So for example, I had a SearchService and a GwtSearchService, which was pretty inefficient.
I hope you like the new approach!
39 responses to “The Command Pattern with the Grails GWT Plugin”
-
Sakuraba September 1st, 2009 at 07:54
That looks nice, can definetly use this when porting our Grails/GWT-app to a cleaner MVP-approach.
Why does gwt-dispatch define serverside components at all? I thought it would focus on being a client-side implementation of the command-pattern. Any idea?
-
If you provide a single GWT service to handle commands, then you need to also provide a mechanism to dispatch commands to different handlers or services.
I noticed in Ray’s talk that he referred to a “contacts” service, so maybe his team use different services as with normal GTW-RPC, but each service implements the command pattern. If this is true, it seems a bit strange to me. Since the information about a request is now encapsulated in an object, you only need one GWT service with a single method to handle them.
Anyway, you’ll find that it’s difficult to write a client-side-only implementation of the command pattern simply because it depends on the server-side implementation.
-
Sakuraba September 1st, 2009 at 14:54
I dont quite get the concept of a “Serverside Actionhandler”, why not dispatch the commands to their appropriate services on the client? That way one can expose his services with GWT-RPC and not add another layer on top of it.
-
Well, I see action handlers as a replacement for GWT-exposed services, rather than as an extra layer. Before action handlers, I would invariably end up with specialised GWT services that simply delegated the work to a normal (unexposed) service. Also, we can potentially do special things with action handlers, such as add support for JSON and XML rendering, that simply wouldn’t fit well with normal services. A service is guaranteed to be called from an HTTP request.
-
Sakuraba September 2nd, 2009 at 12:36
Oh I get it. My exposed services just do the work without delegating anywhere, thats why I didnt get it.
-
I think to be a true Command Pattern, the action class would contain the action behaviour, not the action handler. The action class could have a switch to indicate client- or server- side execution.
If client (eg call REST service, etc), then just do it.
If server-side (eg, service call, DB lookup, etc) send it to a generic server-side ActionPerformer which accepts the actions, makes available any external services, then just calls action.execute() or whatever.
Just an idea..
-
I agree with you it’s not exactly a genuine command pattern implementation. I did consider adding an execute() method to Action, but it opens up a whole world of hurt. You really don’t want a class that has dependencies on both client and server, which is what you would invariably end up with.
The only clean way I can think of doing this is to have separate action classes on the client and server. You would then need to use a neutral serialisation format, such as JSON or XML, instead of Java serialisation. In my view, that would me more effort than it’s worth.
-
Thanks, this is very interesting stuff and I am glad to see the GWT plugin always evolving, it really is a jewel in grails’ crown! Also thanks for your smart gwt & grails intro, really helped to clear a few things up!
Just one thing about the create-gwt-action command, it seems to create the action handler as a Java class, not sure if this is intentional but the semi-colons are missing from the code so I thought maybe not!
I am creating my first Grails plugin (inter-company to begin with) that uses GWT (& SmartGWT) as the view component and was wondering if you could offer some advice… is there any way of figuring out whether the plugin is running standalone or as part of its parent app?? The problem I am facing is trying to create links to the GWT files, right now I have two GSP’s, one that contains:
src=”${createLinkTo(dir: ‘gwt/com.osssoftware.reporting.Dashboard’, file: ‘com.osssoftware.reporting.Dashboard.nocache.js’)}”
for running it stand alone and another that contains:
src=”${createLinkTo(dir: ‘plugins/gwt-and-amchart-0.1/gwt/com.osssoftware.reporting.Dashboard’, file: ‘com.osssoftware.reporting.Dashboard.nocache.js’)}”
for when the plugin is running in a parent app.
If there was a way of figuring out how the plugin was running it would save me some grief.
(There is also a problem when figuring out GWT.getModuleBaseURL() that this might solve too)
Thanks!
John -
Hi John,
Thanks for the feedback. Yes, I messed up with the “create-gwt-action” command. I only discovered it after pushing the snapshot. Hmmm…I don’t appear to have fixed it yet, either. I’m sure I did. Oh well, I’ll upload a new version soon, along with reloading support.
The GSP tags are supposed to handle in-plugin or in-application automatically. If they don’t, I guess that may be a bug. Is the GSP provided by the app or the plugin?
To be honest, I never run a plugin project like that. I always set up test projects and use the in-place plugin mechanism. Take a look at the plugin source code on GitHub to see what I mean. The test projects are under test/projects.
-
I’ve pushed a new version to GitHub.
-
For use with GIN there is no need for creating a provider method to inject GwtActionServiceAsync. The stuff created by GWT.create(…) will automatically be injected. The same with ImageBundles and GWT i18n interfaces.
-
@Jan I use @Provides for the action so that I can set the service endpoint before injecting it. If you don’t mind setting the service endpoint elsewhere, then yes, you don’t have to manually bind the service. Horses for courses I guess
-
[...] This post was Twitted by AndreasArledal [...]
-
Hi Peter,
Thanks for getting back to me.
Regarding building a plugin and testing them by running in a test project: Does this mean you work on your plugin code, package it up, install it into your test project and then run it through its paces in the test project?
Test projects do make sense I suppose, but does this slow down the dev time when you are making and testing numerous small changes??
Just interested as this is my first plugin project and the rest of the company may be asking me for advice quite soon
Thanks again!
John -
Take a look at the source tree for the Shiro plugin. I have a test/projects directory in which I have several Grails projects. In each of them, the BuildConfig.groovy file includes the line:
grails.plugin.location.shiro = "../../.."
With the above setting, the projects will always run with the latest development code of the plugin. I then typically add functional tests to the projects that exercise different configurations of the plugin.
Hope that helps,
Peter
-
Thanks Peter, appreciate the input, that sounds like the nicest way of doing things! Sorry for taking the comments slightly off topic, have a good day!
-
Hi Peter,
Do you have any idea when this will be released into the real world in the grails plugin repo?? Even a rough estimate so I can give it to the higher ups?
Thanks,
John -
John,
It’s already in the real world as a SNAPSHOT. You can install with:
grails install-plugin gwt 0.5-SNAPSHOT
I could release a final version by the end of October, but it’s unlikely to be much different to the SNAPSHOT. I just want to give it some time in my project to see whether any issues crop up. -
Oh great, thanks I thought you just had it up on the link posted previously, thats great!
Thanks! -
Dennis Becton November 2nd, 2009 at 03:00
I know, not the right place to post this, but I was not sure where else to turn?
Anyway, I was wondering if anyone got the 0.4.1 gwt-plugin working with GWT 1.71 on Snow Leopard? I get:
Starting the GWT hosted mode client. …
java? You must use a 32-bit Java runtime to run GWT Hosted Mode. java?
Leopard: Use the Java 1.5 runtime. java?
Snow Leopard: Use the Java 1.6 runtime and add the -d32 flag. java? Java Result: 1Was not sure where to add the flag for the plug-in?
Thanks!
-
Hi Dennis,
You can’t currently add JVM flags for the GWT tools. The relevant issue is here:
http://jira.codehaus.org/browse/GRAILSPLUGINS-1586
You can work around the issue by editing the ~/.grails/<grailsVersion>/projects/<projectName>/gwt-<pluginVersion>/scripts/_GwtInternal.groovy file. You’ll find a “gwtRun” closure in which you can add extra JVM args. Beware, this is a generated directory, so you might delete it by accident.
Cheers,
Peter
-
Using many different services, each following the command pattern is unintuitive, IMHO anyway. I have an example here that has my tentative implementation of the pattern
http://www.chandruon.net/ZaszBlog/post/2009/11/Gin-GWT-Command-Pattern.aspx
and includes some issues that I encountered. Forgive the undocumented code, but it sort of uses the best features in gwt-dispatcher and dependancy injection.
-
Building on my previous comment, Gin needs some .class files as it uses reflection, and I got a lot of NoClassDefFound and ClassNotFound exceptions in the spike app I got working. Am I right in thinking that the grails gwt plugin does not generate .class files for the client side java code? Like, it directly looks through .java files and makes them javascript? However after some time assuming I was on the right track, I managed to get Idea compile the client side java classes so Gin can function.
-
hi peter,
im curious whats the better way of the following two while using the dto plugin:
- let your grails service return a dto directly, or
- let the service return a domain object and do the dto conversion in your ActionHandler?thanks,
zyro
-
@zyro I prefer to return domain objects from the service so that it can be used from controllers and action handlers. It’s then up to the controllers and action handlers to convert them into a form suitable for the client.
-
hi Pete
I’m following this example but I have a problem: how do i import the gwt plugin as a module in the *.gwt.xml file?
i have the following:
but the last line says that it can’t resolve the symbol org.grails.plugins.gwt.Grails. what am i missing here??
i already added the zip file containing the plugin itself in the lib/gwt folder but this does not work….
thanks for your help in advance -
got it fixed Peter. am using the final version so i should
have used grails.plugin.gwt.Grails -
@patria I’ve updated the post to reflect the changes in packages for the final 0.5 release. Thanks for bringing my attention to it.
-
Chris June 1st, 2010 at 06:11
Hi,
I seem to be able to run ok with gwt 1.7.1 and lower, but gwt 2.0.3 seems to have problems in that the same code, urls, everything, but with the new gwt fails.
Have you had a chance to try the 2.0 stuff and have you been successful and if so are there any gotchas to look out for?
I must admit I gave up pretty quickly when it didn’t work
.thank you,
Chris
-
Chris June 1st, 2010 at 06:23
I should be more specific – gwt-rpc calls that work in 1.7.1 and 1.6 etc, etc don’t work for some reason when swapping in gwt 2.0.3. Fails with an exception saying to check the network – but I’m running tests in developer mode all local, so it should work readily enough.
So, if the client side is built and tested with 1.7.1 and the server side with either version, the client works fine. But upgrading the client and building with 2.0.3, even starting with a fresh project from scratch and copying the sources in (I maintain client and server code separate from one another), running the 2.0.3 gwt-rpc code underneath fails to connect – it works for regular servlets doing things the old fashioned way, but, of course, I love grails, so it’s disappointing.
Also, have you gotten a chance to look at the new experimental version of gwt-rpc in the 2.0 release?
thank you,
Chris
-
@Chris I’ve been using GWT 2.0 with version 0.5 of the plugin for some time. What URL is the client trying to connect to? Is it actually a failure to connect, or a 404? You might want to post this to the Google group: grails-gwt@googlegroups.com
-
Hi Peter,
I get the following error when trying to compile gwt modules, any ideas?
grails.plugins.gwt.shared.Action has no available instantiable subtypes. (reached via grails.plugins.gwt.shared.Action)
-
Which version of GWT? Which version of the plugin? Are you using the command pattern, i.e. have you created your own concrete implementations of Action? I don’t ever remember seeing this error, but a Google search indicates it’s something to do with serialization. The Action interface in the plugin should extend Serializable, but perhaps you have an older version in which it doesn’t?
-
I’m using version 2.0.3 of GWT and 0.5.1 of the plugin. I’ve created my own concrete implementation of Action and just checked the interface and it does indeed extend Serializable. Strange…..
-
I actually get this error even without any actions created. As soon as the following is added into the module the compile-gwt-modules doesnt work
GwtActionServiceAsync service = GWT.create(GwtActionService.class);
-
Could you raise a JIRA issue and attach a simple example project so I can try it out? Thanks.
-
I’ve got to the bottom of this now. My action and response implementations were in the wrong package. Following the blog I created them in org.myexample.myapp.client but moving them to org.myexample.shared is what seemed to work with the following in the gwt.xml
-
[...] GWT. With Grails comes the GWT plugin and with it the ability to communicate with Grails using the command pattern. However this pattern uses only one service / servlet facade between Grails and GWT because of [...]
-
Hi I found a rather simple way to integrate the command pattern and the spring security core plugin. I wrote a post about it at:
Have a look..
//Smithimage
Leave a reply





Social Media