Friday, March 19, 2010

Structuring Grails Projects

A Plain Project

Creating a Grails project is damn easy. Just run

grails create-app

and Grails will create the initial project structure with the grails-app folder. The grails-app folder indeed is not just a simple folder but resembles the "convention over configuration" approach - meaning that each folder within it has a predefined meaning to the grails web application framework.


So far so good. But there are times when you are working on applications that go beyond the simple CRUD application style - some call them "enterprise applications". I guess there is no unique definition of what it really means for an application to be an "enterprise application", but there is at least one thing you as a software developer will have to come up with: structuring your application into several components.


Grails indeed has a neat mechanism that supports structuring your applications into several components: plugins.


The Plugin Concept


You might already know that there are hundreds of Grails plugins available - just take a look at http://grails.org/plugins. Even we know plugins of being an integration gateway to other frameworks such as Compass, Spring WebFlow, etc. they can be seen as a great mechanism to create independent components within your application too. 


Let's assume i wanted a component which encapsulates and holds my application's business domain. In my project's folder I already created the main project by running 


grails create-app GrailsEnterpriseApplication


In order to create a separate component for my domain model, i would create a new plugin with


grails create-plugin GrailsEnterpriseDomain


After executing these steps, the overall project's structure will look like this (i.e. in IntelliJ)






Hint: just ignore the two tomcat plugin projects, Grails 1.2.1 defines dependencies on it when creating apps and plugins. 


Since every Grails plugin in fact is a Grails application we can use all the creation and generation commands available in Grails from within that project. For example, running


grails create-domain-class org.ast.User


on the GrailsEnterpriseDomain project will create a new domain class User and the according unit tests in our application's domain plugin. This means that it's possible for another group of developers to work independently on that component, without any restrictions on testing, creating artifacts and so forth.


So far we have not defined a reference between the main project and the plugin. In Grails 1.2.1 this can be done with an entry in the application.properties file in the main project:


plugins.grails-enterprise-domain=0.1


This line in fact means that our GrailsEnterpriseApplication depends on version 0.1 (the initial version) of our GrailsEnterpriseDomain plugin.


The last step for being able to reference our custom plugin at runtime is the execution of the 


grails package-plugin


command on the GrailsEnterpriseDomain project. This command create a zip archive of your plugin but more importantely a plugin.xml file which later on is used by the main application on bootstrap, for loading and resolving possible dependencies of our domain plugin. So if our domain plugin would depend on other plugins, Grails would resolve those dependencies on application startup.


There are several commands and configuration settings to define plugin repositories and push plugins to them, but as it is the case here we just want to use our domain plugin without packaging and deploying it, as this is the case when the initial development work is done. Luckily there is a configuration setting in Grails 1.2.1's BuildConfig.groovy which allows the specification of local unpackaged plugins:


grails.plugin.location.'grails-enterprise-domain' = "../GrailsEnterpriseDomain"


When adding this line to the GrailsEnterpriseApplication's BuildConfig.groovy, Grails on startup instead of using plugin repositories makes a local file system lookup to load the grails-enterprise-domain plugin.


As a consequence running i.e. 


grails generate-controller org.ast.User


in the GrailsEnterpriseApplication project (!) automatically will reference the User class in your domain plugin. Meaning that separating the business model from the MVC part of your application can be done easily.


Summary


Of course, the example just showed a very simple use-case but I think you got the idea. Through Grail's plugin mechanism it is possible to create structured applications with explicit dependencies/automatic dependency resolution and even with revision management included.


[0] Grails Plugin Portal - http://grails.org/plugins
[1] Grails Plugins Introduction - http://grails.org/doc/latest/guide/12.%20Plug-ins.html



No comments:

Post a Comment