I've found myself a bit bored with web application development lately. I've been itching to do something significant with Ruby on Rails for quite some time but always find myself working on Java projects for various clients. At the recommendation of some colleagues I've decided to take a peak at Grails and I have to say that I've shed my boredom and am once again excited about web development.
The following is my review of The Definitive Guide to Grails, written by Graeme Keith Rocher. Prior to reading this book I considered myself to know a lot about Java, a little about Ruby and Ruby on Rails, very little about Groovy, and nothing about Grails. After one speed reading of The Definitive Guide to Grails I have to admit that I'm quite excited at the prospect of starting a new project with Grails.
Yes, that's right, I'm placing the conclusion at the front of the review. Why? Because the reviews of each chapter ended up being much longer than I'd anticipated and I fear few readers will hang on until the end. If you're interested in some of the finer grained details of each chapter please read the following sections that I spent way too much time writing.
I found The Definitive Guide to Grails to be one of the best technical books I've read recently. The book appears to be targeted at the Grails newbie, which would suit just about everyone at this point in time. I never felt the content was over my head nor was I bored with long-winded explanations. I was looking for a book that would introduce me to as many core Grails concepts as possible within a short page count, and Graeme's book certainly delivered.
If you learn best by following along with examples, you're likely to enjoy this book. All eleven chapters are filled with plenty of code examples that not only bolstered my understanding of Grails, but also helped me comprehend some of the finer points of the Groovy language. I found the examples to be straightforward, numerous, and relatively short. I'm not a big fan of the long multi-page examples you sometimes find in technical books. I want enough just enough code to understand the topic and then move on. In my opinion, this is where The Definitive Guide to Grails excels. If you're coming from a Java background, you should be able to pick up on the examples with minimal effort.
Also being new to Groovy, I appreciated the fact that Graeme sprinkled the use of some advanced Groovy features into the code examples. In wasn't a windfall of features mind you, but it was enough to convince me of the power of Groovy and get me excited about learning more.
Overall, The Definitive Guide to Grails was a well-written, informative treatment of an exciting new web development framework. The code examples were woven in very well and really helped to understand the topics. If you're looking to get up to speed on Grails in short order, I think you'll be pleased with The Definitive Guide to Grails.
The following paragraphs provide a quick summary of each chapter.
Chapter 1 - The Search for the Holy Grail(s)
The first chapter provides some insight into the how and why of Grails. Graeme hits on the relative difficulty of developing applications on the JEE platform. He goes on to discuss how the prominence of Ajax and Web 2.0 have focused a lot of attention on web application development, and more specifically efficient web app development.
He then moves onto an introduction of Grails, paying homage to its Ruby on Rails inspiration. There's a short discussion of how Grails leverages the power of the Java platform and specifically the Spring Framework, Hibernate, and Sitemesh.
The remainder of the chapter gets you up and running with Groovy and Grails. Graeme guides you though creating the first pieces of the sample application used throughout the book. Very few concepts are explained at this point, but it does whet the pallet.
Chapter 2 - The Groovy Language
Here's your introduction to the Groovy language from the perspective of a Java developer. The basic topics introduced include classes, assertions, Groovy Strings (GStrings), closures, lists, maps, and Expando objects. Graeme follows up with some "power" features such as Groovy's object-oriented design, Groovy's notion of equals, metaprogramming, and builders.
You shouldn't expect to become an expert on Groovy from this one chapter. For that, consider reading Groovy in Action or Groovy Programming: An Introduction for Java Developers. Luckily, I found most of the topics to be explained in enough detail for me to follow along. A Java or Ruby background is a big help here. Without it, I think you may have a difficult time understanding some of the code samples.
Chapter 3 - The Grails Project Infrastructure
This chapter dives into how a Grails project is organized and configured. If you've ever used Ruby on Rails, you'll notice the project directory structure is similar. Either way, the big benefit here is that there's a common structure for all Grails projects.
Graeme follows up the directory structure discussion with a brief description of Grails and the MVC architecture. At first I groaned about having to read yet another description of MVC, but it turns out that I didn't have to. The whole discussion is only two pages covering where the different Grails components like controllers, views, and the domain model fit into the MVC picture.
The next few pages focus on configuring your data source and logging configuration for different environments. While I welcome the configuration simplicity Grails provides for these resources, I found myself wondering how I would specify other things on an environment by environment level.
The Grails command line utilities, console, and shell are also introduced in chapter three. The command line utilities are very Rails-like, providing you with quick scripts to create things such as applications, controllers, domain objects, tests and tag libraries. The command line can also be used to launch the Grails shell and console. Graeme doesn't spend much time explaining these commands, nor do I think he needs to. Just being aware of them is probably good enough since they're mostly self-explanatory.
The chapter finishes up with a discussion on Eclipse IDE integration. Graeme spends a good six pages describing the integration with plenty of screen shots to guide the reader along. I can't comment on how good the instructions actually are since I didn't try them.
Chapter 4 - The Application Domain
This is the chapter where you really see Grails shine. It's a long chapter mainly covering Grails ORM (GORM) and domain model validation. I felt that Graeme spent a lot of time explaining these two concepts and it really paid off for me.
Grails ORM (GORM)
On the GORM side, he covers the basics of creating Grails domain objects and setting up relationships between them. He then goes on to talk about the various ways to query the database, including dynamic finders and a lengthy discussion on how to leverage the Hibernate Criteria API. The text on using the Hibernate Criteria made it seem relatively trivial to take advantage of the powerful library.
One thing I found strangely missing was a description of how to create the database schema. There were plenty of examples describing how to create the domain model, establish associations, and perform queries, but no description of how to create the necessary tables in the first place. I assume Grails is relying on Hibernate to automatically create the schema, but this is purely a guess since it's not touched upon.
The discussion on domain model validation focuses on how to add simple constraints to individual fields of your domain model. Graeme also describes how to create custom constraints through the use of closures.
Chapter 5 - Scaffolding
Chapter five included a discussion of both dynamic and static scaffolding. Unfortunately (in my opinion), Graeme devotes three-quarters of the chapter to dynamic scaffolding, which I've found to be of little benefit in my brief time playing with the Ruby on Rails equivalent.
He uses dynamic scaffolding to create the first few pages of the sample application, showing the reader screen shots of the UI along the way. There are descriptions of how to modify some of the scaffolding by overriding default CRUD operations and customizing fields with constraints.
I found the text on static scaffolding to be more beneficial. The discussion mainly focuses on using the command line tools to generate default implementations of controllers, views, tests, etc. There's also some brief but clear discussion on the location of generated artifacts and the code that is created behind the scenes.
Chapter 6 - Testing, Testing, Testing
The chapter on testing was split up into two sections, unit testing and functional testing.
The unit testing part of the chapter covered Groovy's assert methods beyond those provided by JUnit and its mocking capabilities through the use of closures. The generous code examples really helped me understand how powerful Groovy's mocking capabilities are. My collegue Scott Leberknight has a nice post that explains some of the finer points of mocking with Groovy if you're interested in some more detail.
In my opinion, you can probably skip the second half of the chapter devoted to functional testing with Canoo WebTest. Although Graeme does a nice job explaining how to use WebTest and its integration with Grails is commendable, I think it will largely be an exercise in frustration for any modern web application using Ajax. As far as I know, WebTest is not able to exercise any Ajax functionality.
Chapter 7 - Grails Controllers
The chapter on Grails controllers covers a lot of ground in a short thirty-one pages, so make sure you're paying close attention when you read it. There's a lot of great information that you won't want to miss. Below are some of the highlights.
Graeme starts off by describing actions, the workhorses of controllers. He does a nice job of describing how Grails use of closures for action definitions is so beneficial. He quickly follows this up by describing how the developer can access various request attributes with little effort. For those of you who've written a lot of Java web applications in the past, you'll be pleased to find that things like request.getSession().getAttribute("attrName") are reduced to session.attrName
The explanation of flash scope will be particularly helpful to anyone who hasn't used Ruby on Rails before. Graeme does a nice job of illustrating how this scope differs from the familiar page, request, session, and servlet context scopes we're all used to and why it's so helpful to have it in your bag of tricks.
Three full pages are devoted to Grails data binding, which builds upon Spring's binding code. Binding is one of the more tedious aspects of web development, but Graeme does a nice job at putting your worries at ease. He also takes the time to describe how binding can be used outside of the context of Grails domain objects.
Graeme follows up data binding with some text on controlling flow with redirects. There's nothing exciting here, although the tactics are well explained.
Grails has a very flexible response rendering framework wrapped up in a simple API. The text covers a wide range of rendering options with short code samples. The discussion of rendering HTML or XML using builders is especially cool.
Think of action interception as AOP for your controller methods, which is exactly how it's described by the author. He gives a quick example of before and after advice followed by a discussion of how action interceptors can be used to implement authentication and authorization. The apparent simplicity of this approach makes me wonder if using Acegi (as briefly described in chapter eleven) is worth the effort.
The last topic in this busy chapter deals with file uploads, which again builds upon Spring's binding technology. Graeme provides two examples of handling file uploads. The first involves pulling the file directly from the request from within a controller. The second example demonstrates binding a file directly to a domain model object.
Chapter 8 - Groovy Server Pages
The chapter on Groovy Server Pages (GSP) is quite long and covers a lot of material. The chapter starts off by talking about some of the more mundane basics; page directives, scriptlets, and GStrings but quickly moves on to more interesting topics.
Graeme starts off the tag discussion by describing the built-in Grails tags. There's at least one usage example for setting variables with tags, logic tags, and iterative tags. These tags probably don't sound all that different than the JSTL ones you may have used, and they aren't. What is different are the filtering and iteration tags, including collect, findAll, and grep. For these more unfamiliar tags, Graeme provides several examples each that demonstrate their usage. He finishes off by talking about Grails dynamic tags, explaining both how to use the built-in Grails ones and also how to create your own.
Validation and Error Handling
Validation and error handling are next on tap. The discussion here is short and to the point. If you've had any experience with Spring MVC before, this text will be quite familiar.
The discussion of internationalization support is very brief, but I didn't find it lacking. You're mileage may vary. It basically boils down to describing where different language bundles are placed in the Grails directory structure and how those messages can be displayed using Grails tags.
Layouts and Templates
Graeme spends a full ten pages describing layouts and templates, more than I would have expected. He provides sample layouts and describes how layouts are selected by convention or through the use of meta tags. This is all the same stuff you'd expect if you've used SiteMesh before.
A discussion of templates follows the text on layouts. Templates are simply reusable snippets of markup. Graeme provides a few examples demonstrating how the g:render tag makes working with templates dead simple. If it weren't for the g:render tag integration, templates would be little more than JSP includes.
Pagination is one of those things that has to be dealt with in every web application, and it's never fun. Here, Graeme explains how the g:paginate tag in Grails makes rendering paging links and managing the display of multiple pages a bit easier. As usual, there are plenty of code examples to help you understand how to use the tag.
Graeme finishes up the chapter with a discussion on how to create your own custom tags and yes, this is different than creating your own dynamic tags. Graeme describes the process through an example of in-place editing that's folded into the example played out throughout the book. I found the example easy enough to understand but the resulting code ugly. It reminded me of the long forgotten days of outputting HTML from servlets.
Chapter 9 - Ajax
Chapter 10 - Services and Jobs
Chapter ten starts with a discussion of the traditional service tier of a Java application. This chapter is also home to the first mention of transactional support from Grails, and it is certainly brief. I have to think there's a lot more to Grails transaction support than Graeme is divulging.
The discussion of services finishes up with a demonstration on the use of the service layer by creating one that calls a del.icio.us web service. The example covers everything from writing the Jakarta Commons HTTP Client to calling the service from a controller.
From services we move to jobs, which Graeme has spent a whopping twenty-six pages describing. Jobs are built on top of the Quartz scheduling engine, and a good portion of the twenty-six pages is devoted to explaining it. He covers all angles associated with jobs, including creating, scheduling, testing, pausing, resuming, and removing jobs. All of this is done through a non-trivial example of a daily scheduled job that queries the database and then formats the results as an email delivered via JavaMail.
Chapter 11 - Java Integration
The last chapter covers Grails integration with Java. The discussion is most heavily weighted towards integration options with Hibernate and Spring. However, Graeme also covers using Acegi for Grails security and exposing a SOAP service using the XFire library. The following paragraphs describe each topic.
ORM Integration with Hibernate
Anyone using Hibernate on an existing project will likely be quite happy after reading this part of chapter eleven. Graeme describes how you can use Grails with an existing domain model and either Hibernate XML mapping files or EJB3 annotations. I have to admit that I had a bit of a smile on my face after reading this section and realizing that I didn't have to wait for an entirely new project to try out Grails.
I was equally surprised to find that I can use Grails constraints on my non-Grails domain objects. Graeme provides an example of how to do this in short order.
Dependency Injection with Spring
The section on dependency injection with Spring shows you how to leverage the Spring Framework underlying Grails. A basic understanding of the Spring Framework will certainly help understand the text, although I don't think it's absolutely necessary.
In the chapter, Graeme talks about how to override Grails beans and how to use Spring controllers with Grails. The explanation of using Spring controllers is much more thorough than I would have expected, with plenty of sample code to help guide the reader.
The section on using Acegi is jam packed with the XML code snippets you need for a basic configuration of the security framework. If you seriously plan to use Acegi, you'll need to look elsewhere for more information. The eight pages of XML is hardly enough to understand what's going on.
Exposing a SOAP Service with XFire
I have a feeling that Apress pressured Graeme into including the chapter on web services with XFire. After all, any respectable book on web development needs to talk about web services. Right? The content was nothing more than a brush pass and had nothing to do with Grails. The text, although well-explained, would have fit just as nicely in any book on JEE web development.