The Command Pattern with the Grails GWT Plugin

A 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:

grails create-gwt-action org.example.myapp.Search
This will create the following files:

  • 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 thoughts on “The Command Pattern with the Grails GWT Plugin

  1. Sakuraba

    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?

  2. Peter Post author

    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.

  3. Sakuraba

    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.

  4. Peter Post author

    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.

  5. Sakuraba

    Oh I get it. My exposed services just do the work without delegating anywhere, thats why I didnt get it. πŸ˜‰

  6. Kit

    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.. πŸ˜‰

  7. Peter Post author

    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.

  8. John Rellis

    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

  9. Peter Post author

    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.

  10. Jan Ehrhardt

    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.

  11. Peter Post author

    @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 πŸ™‚

  12. Pingback: Twitted by AndreasArledal

  13. John Rellis

    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

  14. Peter Post author

    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

  15. John Rellis

    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

  16. Peter Post author

    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.

  17. Dennis Becton

    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: 1

    Was not sure where to add the flag for the plug-in?

    Thanks!

  18. Peter Post author

    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

  19. Chandru

    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.

  20. zyro

    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

  21. Peter Post author

    @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.

  22. patria

    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

  23. Peter Post author

    @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.

  24. Chris

    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

  25. Chris

    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

  26. Peter Post author

    @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

  27. Rus

    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)

  28. Peter Post author

    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?

  29. Rus

    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…..

  30. Rus

    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);

  31. Rus

    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

  32. Pingback: Securing GWT command pattern in Grails | Smithimage

Leave a Reply

Your email address will not be published. Required fields are marked *