Barney and the Holy Grail

Yes, I know it's Lent, but I'm not talking about that Grail – I'm talking about Grails, the web framework for Groovy (the dynamic layer for Java).

I've been looking for a way to ditch CFML for a while now, but nothing has really hit the mark. I keep hoping that Adobe is going to release CF8.1 with Flex 3 and allow all your server-side scripting to be in ActionScript 3, but I'm not holding my breath. The CF platform is pretty nice (excepting the massive bloat), but the CFML language itself just blows ass. So I shop…

I liked SpringMVC/Spring/Hibernate when I was using it, but it's definitely enterprise-y. I've looked at Rails, but I really dislike Ruby's syntax, and ActiveRecord leaves something to be desired (like a query language). Django and Pylons (for Python) are slick seeming, but Python's whitespace-is-semantic paradigm is a big turnoff. My CFRhino "project" actually has some promise, I think, but not something I want to get into maintaining for real application development, and it's JavaScript, which means no real classes and classloading (among other things).

Enter Grails. Like it's counterparts in other languages, it's all about speed of development, but unlike the others, it's all Java. It's built on Hibernate, Spring, and SpringMVC. It compiles to bytecode. It seamlessly integrates with existing Java apps and tools (Quartz, Acegi, DWR, etc.). The paradigms it leverages were incredibly easy to jump into (granted, I've used it's backing tools before), and within a couple hours of seeing both Grails and Groovy for the first time, I had a quasi-functional blog platform.

The past week of developing a first "real" app has borne out my initial impressions to the nth degree. Groovy is a really slick layer that augments Java in just the right ways, without getting the way. Closure are a big deal, vastly superior to simple functions or Java's inner classes. You also get dynamic methods, iterators, native regular expressions, multi-line strings, ranges, a ternary operator (c'mon CF, it's not the 60's), the "elvis" operator which is the ternary operator with the middle clause omitted and the first clause used as it's value, and null-safe dot operator.

But Grails is where it's at.

class User {
  String username
  String password
  String email

  static constraints = {
    username(blank: false, unique: true, size: 4..16)
    password(blank: false, password: true, size: 4..32)
    email(email: true, blank: false)
  }
}

That whopping 11 lines of code is sufficient to create a domain entity with three fields, create validation for the fields, create a Hibernate mapping, and set up all the SpringMVC goodies for binding, form generation/population, error messages, etc.

Request processing, you ask? You have a collection of controllers (think circuits, if you know Fusebox), each of which is a collection of actions (i.e. named closures) corresponding to requests (think fuseactions). So the URL "/login/doLogout" would map to the "doLogout" closure of the "login" controller. Each action closer can redirect, render directly, or return an arbitrary data structre to be passed to a view. By default, the view is a file named to match the action, in a folder to match the controller (you can override, of course), which is written in Groovy Server Pages (GSP). Think JSP, except without the heavy dose of suck. For example, you can define taglibs using Groovy, and then use them in both your views and your controllers, as either tags or as functions.

Grails (thanks to Spring) also provides all-encompassing dependency injection for not only your services and controllers, but for your domain objects as well, which is fantastic. That was one of the larger problems I had with using Spring and Hibernate directly, and one that I never was able to solve in a very satisfactory way. It also provides controller filters which are exceptionally handy (enforcing logins, adding model data for your layouts, etc.).

And the last big piece is SiteMesh, which is the [optional] layout toolkit. You can certainly use GSP for everything; simply include your header/footer as needed and go. But SiteMesh provides basic page wrapping functionality to ease the task, along with a very powerful content dissection/assembly framework (think Fusebox's contentvariables, except managed by the view as they should be).

Finally, yes, there is pretty comprehensive scaffolding support. It doesn't blow my skirt up as much as the other stuff though, but that's probably more a reflection on the type of apps I'm usually building rather than the general utility of the feature.

In case you can't tell, I'm impressed. The Grails guys have done a fantastic job at taking some incredibly flexible and powerful tools and making them ridiculously easy to use.

15 responses to “Barney and the Holy Grail”

  1. Sammy Larbi

    Great post. After my first look at Grails I thought it was so similar to Rails that I didn't need to look further in. This post, coupled with Sean Corfield's two recent posts about Groovy and Grails has made me rethink that position.

    I'll be digging deeper into it at some point.

  2. Mike Brunt

    Barney, thanks for the comprehensive post GRAILS-GROOVY certainly seem worthy of a closer look and I will do so, time permitting. Do you have any thoughts on how easy or hard debugging is? I spend much of my time troubleshooting and fixing applications and ColdFusion has always had great debugging information?

  3. Gerald Guido

    Thank you sir.

    This is just what the doctor ordered. I had a similar experience with rails and python. Java is great but it has a huge learning curve and I am still very much a beginner. But I was able to dig right in with Grails and felt comfortable right off the bat.

    Having support for Eclipse and Netbeans is huge.

  4. Sean Corfield

    Interesting to see you post such a glowing review of Grails after I'd posted two similarly enthusiastic pieces. I only investigated it because of a comment by Dave Ross – after Derek Perez had been bugging me about Groovy. Coincidence or critical mass? :)

  5. Mike Brunt

    I hate to drag out a discussion Barney but why do you believe that CF's relevance is waning? This is a genuine question because from my end of things in the server tuning business I see large entities that were not CF users needing help. Also I don't see any of the associated companies pulling back or financially in trouble (New Atlanta for instance). None of the companies which were spawned from the Macromedia Consulting division have gone. Webapper, Universal Mind etc, in fact Universal Mind were recently listed in the Fortune 500.

    I have no doubt that Groovy and/on Grails is an exciting track to go down but I am not sure that relates to CF being less relevant; just my opinion from indicators that I see. Thanks again.

  6. Marnen Laibow-Koser

    I just wanted to comment on something you said about Rails ActiveRecord. Like you, I've switched away from CF for a variety of reasons; unlike you, I'm currently using Rails, and I very much like Ruby's syntax — it's certainly different from a lot of other languages, but I think it's extremely well designed.

    Anyway, you said that ActiveRecord doesn't have a query language. If I understand correctly what you're getting at, that's not quite true, at least in the sense that you can pass native SQL code to ActiveRecord.find_by_sql . There's certainly nothing in Rails like EJBQL, but to my mind that's OK — who needs to learn yet another dialect of SQL?

    How does Groovy deal with this? I've never worked with it, although my last job was with a company that created what as far as they knew was the largest Groovy project to date. But I wasn't working on that project.

  7. Marnen Laibow-Koser

    As far as I can tell, you're right that Rails ActiveRecord doesn't really support queries of the conceptual object store *as distinct from the database*, but I'm not convinced that that's a problem. I'm not really sure how this feature would be useful in Rails in actual practice. I think there's a feeling that the database *is* the conceptual object store, for all practical purposes. Besides, the ORM is complete enough that it's trivial to add objects to and remove objects from the database as necessary, and this way there's no issue of persistence.

    If I understand correctly what you mean by "business-model-centric way of querying", it should be possible to add that to your Rails models quite easily.

    Also remember that Ruby classes are always open. It probably wouldn't be *that* difficult to extend Rails ActiveRecord to do Hibernate-style queries, although no one has done it so far as I can tell.

    Or am I misunderstanding?

  8. Marnen Laibow-Koser

    OK, now I see your point. There are two issues here, then: query syntax and decoupling entity names from the database.

    Query syntax is less problematic then you seem to suppose. Even without using find_by_sql, Rails has dynamic finder methods that will cover even fairly complex cases (you can do things like find_by_first_name_and_zip_code if you really need to, for example).

    As far as entity names go, it's easy to use set_table_name and set_primary_key to tell Rails that the names of the table and primary key field are not what you'd think from the class name, so the only stumbling block is the attribute names. It's not well known, but a little digging unearthed the alias_attribute method, which allows you to easily create an alias for any attribute, so that you can do

    class Customer < ActiveRecord::Base
    set_table_name 'tbl_Customrz'
    set_primary_key 'int_cust_id'

    alias_attribute :name, :varchar_firstname_lastname
    end

    This will let you read and write to Customer#name. That leaves dynamic finder methods as the only real issue — in the current version (2.1.0), they don't appear to work with aliased attributes, but there's a patch at http://dev.rubyonrails.org/ticket/11354 that apparently fixes that problem (although I haven't tried it).

    For one model made up of multiple tables, I would probably just create a DB view, or an abstraction layer of mediating objects. composed_of might come in handy here.

    My point, then, is that Rails ActiveRecord does indeed have a suitable query language that can be uncoupled from the database. You don't hear much about it because Rails developers don't tend to use it that way, but it *does* exist.

  9. Peter Bell

    Hi Barney,

    Just wondering if you still play around with Grails these days?
    Peter