My view of GWT is changing. When I wrote 5 GWT Anti-Patterns I saw it as the framework controlling my entire application. Now it’s my glue.
GWT is a wonderful foundation holding together the different parts of your application. It can grow and expand to new technologies and uses we haven’t thought of yet, but it can also hold us back. You can get stuck in GWT and never find your way out.
Each of these four anti-patterns addresses different ways to write code you wish you hadn’t. The solutions are all about opening doors instead of closing them.
1. GWT RPC
GWT RPC is the sexiest feature of the entire toolkit. Making AJAX simple lets you program for the web like it was a desktop. Don’t worry about remote communications or networks, GWT RPC takes care of that for you.
The problem
GWT RPC generates the network calls for you and automatically marshals Java objects between the browser and the server, but that ease of use comes at a cost.
It isn’t that easy. GWT RPC requires you to manage two interfaces plus the client-side calling code and a servlet to make it all work.
Error handling is hard. Network programming is the art of error handling. Networks are unpredictable and abstracting that away makes it much harder to respond well when something doesn’t go right.
You can’t tell what’s going on. Try debugging your GWT RPC through a network tool like Wireshark or HTTPFox. All the ease of debugging your Java by looking at the byte code.
It’s slow. GWT RPC adds a lot of overhead to the request, but that isn’t the worst part. When you think of remote procedure calls as free you make a lot of them. That’s the recipe for an application that loads in minutes instead of seconds.
The solution
Use REST. I’ve written patterns for using REST from GWT. There are also some good built-in features and third-party plugins to support it. REST looks daunting at first, but it isn’t that bad.
REST is everything GWT RPC isn’t: fast, easy to debug, and simple. It also does more.
REST forces you to build an API. GWT RPC makes everything look like the same program so you rarely create a solid API. With REST you have to. APIs make your code better even if nobody else ever calls them.
REST supports automated testing. Once you have a REST API you can test it without worrying about the client. I’ve written test suites in Ruby just to make sure I had good coverage.
REST decouples the client and server. Imagine shipping a new version of your GWT client without changing your server. You could fix bugs and not worry about destabilizing other parts of your code. You could even write a GWT client for a server written in a different language like we did when we created a multi-value auto-complete field with GWT and REST. That article has source code of a GWT application that calls to a Java servlet or PHP using REST.
2. Securing your GWT application
I sleep peacefully at night knowing my applications are secure. So do my customers.
GWT doesn’t solve the security problem for you so you might be tempted to put it all behind a firewall, password, or Spring framework and get perfect security. Perfect security isn’t perfect.
The problem
It’s easy to put your entire GWT application behind a secure framework. Require a login before you can even download the HTML. You feel happy knowing the bad guys can’t see your JavaScript, HTML, or CSS, but securing everything makes your application less secure.
The solution
In the end GWT is just a web page. People download, run it, and maybe view the source. Let them. Don’t secure any of the files that GWT generates and don’t put secure information in your source code.
Secure your data, not your code. It doesn’t matter if you’re using GWT RPC, REST, or anything else, you’re just exposing URLs with data. That’s the right place to put your security.
Create a single path, put all of your data behind it, and secure it with a servlet filter. You can make this path something like /data
so your URLs look like /data/users
or /data/roles
. That simple path is easy to secure and easy to test.
You can even go a step further and move the code serving secure data into a separate WAR file. That avoids many accidental security problems.
Securing just your data makes your server easier to write and test. It also helps your browser code. Don’t make login a separate step in your application. Add a single point in your client for login and make it part of your GWT application.
3. Using only GWT
GWT is an insular environment. It separates you from JavaScript and can cut you off from a world of innovations and well tested software.
The problem
There are many frameworks that wrap existing JavaScript code. They work well, but they’re little more than a drop in the bucket. GWT is a great project, but it can’t keep up with the rest of the Internet.
The solution
Wrap existing third-party Javascript with GWT. For example, GWT doesn’t have a progress bar control and JQuery UI has a really nice one. Wrapping the JQuery UI progress bar is easy. Here’s all the code you need:
import com.google.gwt.user.client.ui.SimplePanel; public class ProgressBar extends SimplePanel { private int m_value = 0; public ProgressBar(String id) { getElement().setId(id); } @Override public void onAttach() { super.onAttach(); addProgressBarJS(getElement().getId(), m_value); } public int getValue() { return m_value; } public void setValue(int value) { m_value = value; setValueJS(getElement().getId(), m_value); } private static native void setValueJS(String id, int barValue) /*-{ $wnd.$('#' + id).progressbar('destroy'); $wnd.$('#' + id).progressbar({ value: barValue }); }-*/; private static native void addProgressBarJS(String id, int barValue) /*-{ $wnd.$("#" + id).progressbar({ value: barValue }); }-*/; } |
That’s it. Add JQuery and JQuery UI to your GWT HTML page, include the JavaScript files in your WAR, and write 42 lines of code. Now you have access to the JQuery progress bar in GWT and you’ve added strong typing to the control.
Don’t like the JQuery progress bar? Wrap someone else’s. You can always change your mind later, since none of the calling classes know you’re using it. I’ve wrapped the progress bar, the date picker, and half a dozen third-party JavaScript controls.
4. Using GWT for layout
We all know the evils of FlexTable, but we need to go further. The layout technology of the web is CSS.
The problem
GWT provides FlexTable
, DockLayoutPanel
, VerticalPanel
, and many others to do layout in HTML. They put the layout in your code and make GWT feel a lot like Swing. So why shouldn’t you use them?
They’re ugly. CSS isn’t just for aesthetes. Look at any big professional website – Google, Amazon, Facebook – they all live and breathe CSS. Without it you can’t really control or customize how your application looks.
You have to recompile. Needing to recompile for every pixel you change hurts your productivity. It also means your customers can’t customize your application after you’re done with it.
You can’t use Firebug. All user interfaces require tweaking and Firebug lets you do it live. Stick with HTML layouts and you’re poking around in the dark hoping your changes are OK.
The solution
Put all of your layout in CSS. This was one of our fundamental rules on my last project. Assign classes to your elements, write tags first GWT, and make a professional application.
Conclusion
Our understanding of good on the web is changing. Just working isn’t enough anymore. Good applications run fast, look professional, and are easy to use. Most of these anti-patterns are advanced. They represent subtle new ways of thinking about GWT. Patterns at this level are a sign of maturing technology and our maturing understanding of it.