tags:

views:

354

answers:

2

Hi.

I'm playing with a GWT/GAE project which will have three different "pages", although it is not really pages in a GWT sense. The top views (one for each page) will have completely different layouts, but some of the widgets will be shared.

One of the pages is the main page which is loaded by the default url (http://www.site.com), but the other two needs additional URL information to differentiate the page type. They also need a name parameter, (like http://www.site.com/project/project-name. There are at least two solutions to this that I'm aware of.

  1. Use GWT history mechanism and let page type and parameters (such as project name) be part of the history token.
  2. Use servlets with url-mapping patterns (like /project/*)

The first choice might seem obvious at first, but it has several drawbacks. First, a user should be able to easily remember and type URL directly to a project. It is hard to produce a human friendly URL with history tokens. Second, I'm using gwt-presenter and this approach would mean that we need to support subplaces in one token, which I'd rather avoid. Third, a user will typically stay at one page, so it makes more sense that the page information is part of the "static" URL.

Using servlets solves all these problems, but also creates other ones.

So my first questions is, what is the best solution here?

If I would go for the servlet solution, new questions pop up.

  1. It might make sense to split the GWT app into three separate modules, each with an entry point. Each servlet that is mapped to a certain page would then simply forward the request to the GWT module that handles that page. Since a user typically stays at one page, the browser only needs to load the js for that page. Based on what I've read, this solution is not really recommended.

I could also stick with one module, but then GWT needs to find out which page it should display. It could either query the server or parse the URL itself.

  1. If I stick with one GWT module, I need to keep the page information stored on server side. Naturally I thought about sessions, but I'm not sure if its a good idea to mix page information with user data. A session usually lives between user login and logout, but in this case it would need different behavior. Would it be bad practise to handle this via sessions?

The one GWT module + servlet solution also leads to another problem. If a user goes from a project page to the main page, how will GWT know that this has happened? The app will not be reloaded, so it will be treated as a simple state change. It seems rather ineffecient to have to check page info for every state change.

Anyone care to guide me out of the foggy darkness that surrounds me? :-)

A: 

I'd go with History tokens. It's the standard way of handling such situations. I don't understand though, what you mean by "It is hard to produce a human friendly URL with history tokens" - they seem pretty human friendly to me :) And if you use servlets for handling urls, I think that would cause the whole page to be reloaded - something which I think you'd rather want to avoid.

Second, I'm using gwt-presenter and this approach would mean that we need to support subplaces in one token, which I'd rather avoid.

If you are not satisfied with gwt-presenter (like I was :)), roll out your own classes to help with MVP - it's really easy (you can start from scratch or modify the gwt-presenter classes) and you'll get a solution suited to your needs. I did precisely that, because gwt-presenter seemed to "complicated"/complex to me - to generic, when all I needed was a subset of what it offered (or try to offer).

As for the multiple modules idea - it's a good one, but I'd recommend using Code Splitting - this type of situation (pages/apps that can be divided into "standalone" modules/blocks) is just what it's meant to be used for, plus you bootstrap your application only once, so no extra code downloaded when switching between pages. Plus, it should be easier to share state that way (via event bus, for example).

Igor Klimer
I agree that history tokens seems like the intuitive choice, but I'm still not convinced that it is optimal :-). What I mean with non human friendly URLs is that GWT history prefixes the token with a # (which most users won't remember). Also, since users typically expect an url to consist of / only, I would need to use / as both place and parameter separator, which is hard to maintain. Or am I missing something related to history handling here?I do agree that code splitting would make sense with this solution.
Andreas Borglin
The whole point of users "remembering" the url doesn't quite get to me (but then again, I don't know what sort of page you are working on and who the users might be) - I don't think anyone tries to remember urls nowadays, not when there are sites like del.icio.us, people bookmark sites they visit often. Besides, the hash/# in address is not something Google came up with, it's the standard way all browsers use and support, usually referring to an `id` of a DOM element, but in case of web application - to its state. Gmail uses it, as does an increasing number of web sites.
Igor Klimer
Andreas Borglin
Igor Klimer
A: 

Hi there Andreas!

Based on what you have posted I presume you come from building websites using a server side framework: JSP, JSF, Wicket, PHP or similar. GWT is not the solution for building page-based navigational websites, like you would with the aforementioned frameworks. With GWT, you load a webapp in the browser and stay there. Handle user events, talk with the server and update widgets; using gwt-presenter is a good thing here as you are forced to think about separation of controller logic and view state. You can really exploit all features of GWT to build a high-performance app-in-the-browser, but it is definately not meant for building websites (using hyperlinked pages that transfer request parameters via the server session).

This is by far the most widely asked question about GWT here @ StackOverflow :) "How do I define pages and navigation between them in GWT?" Short answer: "You don't."

Use Wicket instead, it runs on the App Engine just fine and enables you to define page bookmarks and all stuff you mentioned above. Look here: http://stronglytypedblog.blogspot.com/2009/04/wicket-on-google-app-engine.html

Jeroen