Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

Tuesday, 24 March 2009

Why Grails Is Good

Obviously I can't say that Grails is the best thing since sliced bread and then not present some evidence to support my claim, so here's a specific example.

In my application I have a Network domain class and some other domain classes that extend it - TwitterNetwork, FacebookNetwork, etc. I wanted to handle the CRUD functionality for these classes in a single controller, but keep the forms separate. Having auto-generated the controller + views and then deleted the stuff I didn't want, here's the structure I ended up with:
- grails-app
- domain
- Network.groovy
- FacebookNetwork.groovy
- TwitterNetwork.groovy
- controllers
- NetworkController.groovy
- views
- network
- list.gsp
- facebookNetwork
- create.gsp
- edit.gsp
- twitterNetwork
- create.gsp
- edit.gsp
Out of the box, the default list action just works:
def list = {
if (!params.max) params.max = 10
[ networkInstanceList: Network.list(params) ]
}

As do the delete, save and update actions.

All I have to do now is get the edit and create actions to use the correct view, depending on the network type. To do this I use the class name to determine which view to use. For example, here's my edit action:
def edit = {
def networkInstance = Network.get(params.id)
renderEditForm(networkInstance)
}

def renderEditForm(network) {
def map = [ networkInstance : network ]
def viewPath = getViewPath(network)
render(view:"/${viewPath}/edit", model:map)
}

// derive the view path from the given network instance
def getViewPath(network) {
def networkName = getName(network)
networkName[0].toLowerCase() + networkName[1..-1]
}

The great thing is, I know that will work because by convention Grails will put the views for TwitterNetwork in the twitterNetwork folder and the views for FacebookNetwork in the facebookNetwork folder. It then becomes a simple case of taking the class name and making the first character lower case.

I use the same principle for my create action:
static networks = [ "twitter" : TwitterNetwork,
"facebook" : FacebookNetwork ]

def create = {
def networkInstance = createNetwork(params.type)
networkInstance.properties = params
renderCreateForm(networkInstance, params.type)
}

// create a new network instance of the given type
def createNetwork(networkType) {
if (networkType in networks.keySet()) {
def clazz = networks[networkType]
return clazz.newInstance()
}
}

... etc

And that's it! Full CRUD functionality for a set of polymorphic domain classes in a few lines of code - most of which were auto-generated by the framework. :-)

Wednesday, 11 March 2009

Is Grails The Answer?

I certainly think so. Over the last few years, I've used a variety of Java web frameworks such as Struts, Spring MVC + Tapestry and various combinations of Spring, Hibernate, JPA + EJB. Before all those things came along, I even tried my hand at JSP's, vanilla servlets + JDBC. I got some decent results out of most of those frameworks, but at the same time, it was hard work and productivity wasn't very high on the agenda. However, once things like Rails + Django appeared on the scene, I started to wonder if I should be using Java in the first place? These new frameworks made use of more dynamic languages - Ruby and Python - and promised short development cycles and extremely high productivity.

But, having spent the best part of ten years becoming a Java expert, moving to an entirely new platform seemed like a very big jump - particularly in the case of Ruby/Rails. After all, the JVM is (in my opinion) one of Java's biggest strengths - if only there was an easier way to tap that potential. Enter Groovy + Grails! I'd been following Groovy pretty closely for a while and really liked the look of it, eg. its extensive use of closures. I was also aware of Grails, but the name put me off slightly - it just seemed to be shouting "me too!" a little too loudly for my liking. But following my disappointment with Google App Engine, I decided it was finally time to take the plunge.

I needn't have worried. Quite simply, Groovy + Grails is the best web framework I have ever used in any language. After just one day (which included frequently referring to the documentation) I had full CRUD functionality for a set of polymorphic domain classes. Following that, adding an Authentication Filter was a breeze, creating a Custom Tag Library was incredibly easy and even Ajax Integration (so often where complexity starts to creep in) wasn't too unpleasant. And here's the best part ... all these features build on my existing knowledge of Servlets, Spring, Hibernate, etc, so I'm not learning a whole new technology stack from scratch.

After three days I had an application that was every bit as functional as its Google App Engine equivalent, which took a similar amount of time. I'll admit that I haven't strayed too far from the golden path, but so far, all the signs are extremely encouraging. There's plenty of support out there and the user community is extremely active. I've also read reports of companies using Grails for real-world sites, which is more than some of the latest frameworks can boast. I'll keep you posted ...

Friday, 6 March 2009

Google App Engine - Final Thoughts

I was a little disappointed with Google App Engine. While I concede that it allows you to get some VERY quick results, what started out as niggling doubts at the start of the project soon became genuine concerns:

1) The whole thing seems to be a bit muddled. They're kind of half-supporting an old version of Django, meaning that some Django features are available but some are not. For example, if you try to do a server-side password field as suggested in the Django docs, it doesn't work.

2) No guidance on project structure, unit testing, etc. The approach adopted by most people seems to be 'lump everything in one folder' which leads to a very disorganised project. By contrast, Groovy + Grails has clearly defined areas for domain models, controllers, views and tests.

3) You're tied to Google's technology. Running a GAE app outside the App Engine environment is not simply a case of flicking a switch. Similarly, you would need to do a significant amount of work to get a Django app to run on app engine.

4) Out of the box, you don't even have access to the session! Everything has to be done with the datastore, which feels very restrictive.

5) Your request handlers implement get, post, etc which map directly to HTTP methods. For me, this level of abstraction is too low - in the last few years the Java community have progressed onto controllers + actions which seems to be a better fit for implementing complex behaviour.

6) Persistent entities must extend a database Model class. Worse still, if you intend to create multiple sub-classes of that class, you should extend PolyModel. Again, this kind of thing has been frowned upon by the Java community for some time. By contrast, a model in Groovy + Grails looks like this:
class User {

String email
String password

static hasMany = [networks: Network]

static constraints = {
...
}
}
Note that it does not need to extend anything (ie. the domain model is decoupled from the persistence strategy) and is given the ability to get, save and delete itself at runtime.

That said, I don't suppose that I'm the target market for GAE. Just the fact that hosting is provided will be a massive draw for a lot of people and I doubt there's anything better if you're wanting to create a quick and dirty mashup of some 3rd party services.