Introduction To Grails
By Jeff Brown, OCI Principal Software Engineer
March 2007
Introduction
The Grails framework is a framework for agile web development using Groovy and Java. There are already a lot of frameworks for building web applications in Java, so one may ask "Why another web framework for the Java platform?" or "What really sets the Grails framework apart from all of the other choices?". This article aims to help answer those questions and others by demonstrating how simple it can be to build web applications with the Grails framework.
By leveraging the power of a coding-by-convention paradigm and combining that with a stack of best-of-breed Java technologies, the Grails framework provides a set of tools that greatly simplify the task of building web applications for the Java platform. The technologies that the Grails framework builds upon include Spring, Hibernate, Sitemesh, Quarts, and others. The flexible, dynamic nature of Groovy ties all of that together in a way that developers will find refreshingly simple to deal with.
This article provides an introduction to the Grails framework, including coverage of the basics needed to get started developing applications with it. References to texts providing comprehensive coverage of the Grails framework are included at the end.
Coding By Convention
Coding by convention is one of the techniques that the Grails framework uses to help developers build and maintain web applications without a lot of complexity. Coding by convention results in very little configuration being required in a typical Grails application. This means that more of your effort and more of your code is directly related to the application requirements, and less is related to configuring the framework.
For example, in a Grails application, a typical HTTP request will be handled by some controller, and the controller will then render some view back to the client. There is no configuration file necessary to map a request to a specific controller, and no configuration file is involved in deciding which view corresponds to that particular request. All of that can be managed by following some basic conventions. Several examples of this will be shown later in this article.
Installing Grails
Getting a development environment in place to support building web applications with the Grails framework is made very simple by the fact that the Grails framework bundles almost everything needed in one neat package.
The Grails framework does not require a lot of dependencies that need to be installed and configured. There is no need to download and install Hibernate or Spring or any of the other libraries that the Grails framework is built on. You will need a JDK (1.4 or later). No special editor is required. Your favorite Java IDE will work. NetBeans, IntelliJ IDEA, and Eclipse are all fine IDEs for Grails development. You might find that lighter-weight development tools are all that is required to maintain Grails applications.
The Grails framework may be downloaded from http://grails.org/download. At that site you will find the latest stable release, as well as development snapshots.
Note that the development snapshots are not necessarily stable and may contain partially implemented features. The snapshot releases posted to that page are the result of the latest successful builds from the Cruise Control build machine.
At the time of this writing, 0.4.2 is the latest stable release and all of the code described in this article will work fine in that release.
Once you have downloaded a release in either zip or tar.gz format, extract the archive to some place on your file system where you choose to store development tools. You will need to set an environment variable called GRAILS_HOME
to point to the Grails installation directory and modify your PATH environment variable to include $GRAILS_HOME/bin
.
Getting Started
Very quickly you should be able to get a simple Grails application up and running with support for basic create, read, update, and delete (CRUD) operations for a simple domain class. The steps here will take you through creating your first Grails application very quickly. Later we will cover more details. The goal with this first application is to get the most basic application up and running.
The first step is to create an empty application.
Like most development tasks in Grails, creating the application is a simple task. The Grails framework provides a number of command line actions that may be invoked as arguments to the grails
command.
The command to create a new application is called create-app
. The create-app
command accepts an argument that is the name of the application to be created. The command shown below creates an application called testapp.
$ grails create-app testapp
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article
Environment set to production
Note: No plugin scripts found
Running script /Users/jeffbrown/Tools/grails/scripts/CreateApp.groovy
[mkdir] Created dir: /Users/jeffbrown/article/testapp/src
[mkdir] Created dir: /Users/jeffbrown/article/testapp/src/java
[mkdir] Created dir: /Users/jeffbrown/article/testapp/src/groovy
[mkdir] Created dir: /Users/jeffbrown/article/testapp/src/test
( ... )
The create-app
command has created a shell Grails application in the testapp/
directory. Once the application is created, all other Grails commands should be executed from within the project directory.
The next command to execute is the create-domain-class
command to create our first domain class. Create a Person
domain class.
$ grails create-domain-class Person
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article/testapp
Environment set to production
Running script /Users/jeffbrown/Tools/grails/scripts/CreateDomainClass.groovy
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-app/domain
Created at /Users/jeffbrown/article/testapp/grails-app/domain/Person.groovy
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-tests
Created Tests at /Users/jeffbrown/article/testapp/grails-tests/PersonTests.groovy
The create-domain-class
command has created an empty domain class in grails-app/domain/Person.groovy
and has created a unit test class at grails-tests/PersonTests.groovy
. Open the Person.groovy
file in your favorite text editor and add a few simple attributes.
- class Person {
- String firstName
- String lastName
- Integer age
- }
Next, create a controller for the Person
class by executing the create-controller
command.
$ grails create-controller Person
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article/testapp
Environment set to production
Running script /Users/jeffbrown/Tools/grails/scripts/CreateController.groovy
[mkdir] Created dir: /Users/jeffbrown/article/testapp/grails-app/views/person
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-app/controllers
Created Controller at /Users/jeffbrown/article/testapp/grails-app/controllers/PersonController.groovy
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-tests
Created ControllerTests at /Users/jeffbrown/article/testapp/grails-tests/PersonControllerTests.groovy
Edit PersonController.groovy
and add a property called scaffold
and assign that property a value of true for now to enable dynamic scaffolding for the Person
class.
- class PersonController {
-
- def scaffold = true
-
- }
That is it. Everything is in place to run a basic CRUD application. Execute the run-app
command to start the application.
$ grails run-app
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article/testapp
Environment set to development
Running script /Users/jeffbrown/Tools/grails/scripts/RunApp.groovy
Compiling sources...
[mkdir] Created dir: /Users/jeffbrown/article/testapp/web-app/WEB-INF/lib
[mkdir] Created dir: /Users/jeffbrown/article/testapp/web-app/WEB-INF/spring
[copy] Copying 33 files to /Users/jeffbrown/article/testapp/web-app/WEB-INF/lib
( ... )
FrameworkServlet 'grails': initialization completed in 87 ms
Servlet 'grails' configured successfully
That last line of output there is your sign that the application has started successfully.
Access the application by pointing your web browser at http://localhost:8080/testapp/ where the standard Grails application welcome page should be displayed including a link to the Person
controller. Following that link you can navigate around using the dynamically generated scaffolding code which provides CRUD capabilities to manage Person
objects. The interface is very intuitive and simple to interact with.
Note that while running in development mode, by default your Grails app will save data to an in-memory HSQL database. The configuration for the application's data source may be found in grails-app/conf/DevelopmentDataSource.groovy
, which looks like this:
- class DevelopmentDataSource {
- boolean pooling = true
- String dbCreate = "create-drop" // one of 'create', 'create-drop','update'
- String url = "jdbc:hsqldb:mem:devDB"
- String driverClassName = "org.hsqldb.jdbcDriver"
- String username = "sa"
- String password = ""
- }
The data source configuration file may be modified to suit your development needs. The default in memory database is very nice for doing iterative development while your domain model may be changing frequently.
MVC In Grails
The Grails framework takes advantage of the Model-View-Controller (MVC) design pattern to partition responsibilities within the application and to simplify the application architecture.
- Model classes should represent the domain objects in your system.
- Controller classes should control the flow of the application.
- View artifacts should focus on presentation.
Following conventions recommended by the Grails framework will keep your application clean and will help make the application flow easier to follow.
In the simple example above, a single domain class was defined in grails-app/domain/Person.groovy
. A controller was defined in grails-app/controllers/PersonController.groovy
that was configured to use dynamic scaffolding. Since the dynamic scaffolding was enabled, all of the view resources were created at runtime. For a simple admin interface the dynamic scaffolding may be fine, but for most real applications, view artifacts will need to be created.
Grails Controllers
In order to get a better understanding of how Grails controllers work, we will extend the testapp
to use generated scaffolding instead of dynamic scaffolding.
Generated scaffolding is similar to dynamic scaffolding, except that generated scaffolding is created before runtime and may be modified to suit your application needs.
The generated scaffolding in Grails is often a good starting point and can serve as a way to learn 'The Grails Way.' Looking at the generated code is a great way to get started.
To generate scaffolding for the Person
class, run the generate-all command
.
Note that since we already have a
PersonController
class, the Grails framework will ask us to confirm that we want to overwrite that class. Alternatively you may choose to delete the controller before runninggenerate-all
.
$ grails generate-all Person
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article/testapp
Environment set to production
Running script /Users/jeffbrown/Tools/grails/scripts/GenerateAll.groovy
Compiling sources...
[delete] Deleting directory /Users/jeffbrown/article/testapp/web-app/WEB-INF/grails-app
[mkdir] Created dir: /Users/jeffbrown/article/testapp/web-app/WEB-INF/grails-app/views
[mkdir] Created dir: /Users/jeffbrown/article/testapp/web-app/WEB-INF/grails-app/i18n
( ... )
Generating controller for domain class [Person]
Controller PersonController.groovy already exists. Overwrite?y,n
y
Controller generated at ./grails-app/controllers/PersonController.groovy
After the scaffolding is generated, take a look at grails-app/controllers/PersonController.groovy
. You will see that the controller defines a number of closure properties including list, show, delete, edit, update, create and save. These closure properties are mapped to URLs by convention, so that a URL like http://localhost:8080/testapp/person/list/ will invoke the list closure in the PersonController
class.
The default scaffolded list closure property should look something like this:
- def list = {
- if(!params.max)params.max = 10
- [ personList: Person.list( params ) ]
- }
This closure is returning a Map that has 1 entry in it. The key for that entry is personList
, and the value associated with that key is a list of Person
objects returned from the Person.list(params)
call.
You may notice that our Person
class did not define a List
method. The method being invoked here is one of the many dynamic methods that Grails adds to all domain classes. The Groovy Object Relational Mapping tool known as GORM provides very powerful and flexible query mechanisms like this. At the end of this article is a reference to the documentation where all of the dynamic methods added to domain classes are described in detail.
This particular controller action doesn't specify a view to be rendered, so Grails will assume convention and render the List
view. If a controller action doesn't explicitly call for a view to be rendered, the view matching the controller action name will be rendered.
To demonstrate how a controller might request a specific view be rendered, add a new controller action to the PersonController
. The List
property shown above is designed to show all Person
objects. Define a new controller action that is designed to show all young people. Consider that a young person is anyone under the age of 16. Add a controller action to the PersonController
class that looks like this:
- def listYoungPeople = {
- render(view:'list', model:[personList: Person.findAllByAgeLessThan( 16 ) ])
- }
The listYoungPeople
controller action is invoking the render
method to render a specific view. A Map
is being passed to the render
method that includes the view to be rendered and the data being passed to that view.
In this case, the view to render is the List
view. The data being passed to the view is similar to the data rendered from the List
action, but instead of invoking Person.list()
, this controller is invoking another dynamic method called Person.findAllByAgeLessThan( 16 )
.
Here you should get a sense for the power and flexibility of the GORM dynamic methods that are added to Grails domain classes. That method name is very easy to read and clearly expresses the intent of the method.
Create several Person
objects in your system, some with ages greater than or equal to 16 and several younger than 16. With that data in place take a look at the differences you see when you visit http://localhost:8080/testapp/person/listYoungPeople vs. http://localhost:8080/testapp/person/list.
Grails Views
The PersonController
class now has 2 separate controller actions that each render the list
view. The code associated with this view may be found in grails-app/views/person/list.gsp
. JSP developers will find the syntax in a Groovy Server Page (GSP) to be familiar.
The main difference between JSPs and GSPs is that GSPs may contain embedded Groovy code where JSPs may contain embedded Java code.
Grails bundles a rich set of tag libraries that simplify the code in GSPs. The process of creating your own custom tag libraries for Grails could not be more simple. Like most Grails application artifacts, Grails tag libraries are plain Groovy classes.
To create a new tag library, simply create a Groovy class in grails-app/taglib/
with any name that ends in TagLib
. The file may be created by hand or may be created with the create-tag-lib
command.
$ grails create-tag-lib TestApp
Welcome to Grails 0.4.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/jeffbrown/Tools/grails
Base Directory: /Users/jeffbrown/article/testapp
Environment set to production
Running script /Users/jeffbrown/Tools/grails/scripts/CreateTagLib.groovy
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-app/taglib
Created TagLib at /Users/jeffbrown/article/testapp/grails-app/taglib/TestAppTagLib.groovy
[copy] Copying 1 file to /Users/jeffbrown/article/testapp/grails-tests
Created TagLibTests at /Users/jeffbrown/article/testapp/grails-tests/TestAppTagLibTests.groovy
The newly created grails-app/taglib/TestAppTagLib.groovy
file may be edited to contain any number of custom tags.
To create a new tag, add a new closure property to the TestAppTagLib
class that accepts a single argument. The argument will contain any attributes passed to the tag.
Here is an example tag:
- class TestAppTagLib {
-
- def myTestTag = { attrs ->
- out << "This Is My First Custom Tag"
- }
-
- }
That new custom tag may be invoked from any GSP in the application. Modify grails-app/views/person/list.gsp
to execute this tag. Immediately after the openingtag
add the following:
<g:myTestTag></g:myTestTag>
The next time you point your browser at http://localhost:8080/testapp/person/list you should see the output of the myTestTag
rendered in the browser.
The tag shown above does not do anything special with any parameters passed to the tag. Change the myTestTag
closure property to look like this:
- def myTestTag = { attrs ->
- def numberOfOccurrences = Integer.valueOf(attrs[ 'occurrences' ])
- numberOfOccurrences.times {
- out << "This Is My First Custom Tag"
- }
- }
This version of the tag expects an attribute named occurrences
that represents the number of times that the message should be output. Change the list GSP to invoke that tag like this:
<g:myTestTag occurrences="3"></g:myTestTag>
Point your browser at http://localhost:8080/testapp/person/list and notice that the message now appears 3 times.
This trivial example only begins to demonstrate the power and flexibility provided by the Grails framework's custom tag lib support.
Grails Domain Classes
In many ways a Grails application revolves around the domain classes (also known as model classes). Example domain classes are Car
, Person
, Appointment
, Note
, Ticket
, etc. These are the things that are typically stored in the database. In the examples above the Person
class is a domain class.
The Person
class shown above is a simple class that declares 3 properties. The properties are FirstName
, LastName
and Age
.
A Grails domain class may also declare validation constraints to help impose business rules. Validation constraints may be added to a domain class in the form of a static closure property named Constraints
. For example, if you have business rules that say a Person
's age must be greater than 21 and the FirstName
and LastName
properties must contain at least 2 characters and no more than 35 characters, the Grails framework provides a simple way to express that.
- class Person {
- String firstName
- String lastName
- Integer age
-
- static constraints = {
- age(min:21)
- lastName(length:2..35)
- firstName(length:2..35)
- }
- }
Now if an attempt is made to save a Person
with data that violates any of those rules, the save will fail. The default scaffolding views provide feedback to inform the user that validation has failed. Your application may do with this information whatever is most appropriate.
What Next?
The trivial application described above only begins to demonstrate the powerful capabilities of the Grails framework. A great next step is to build a simple application of your own and start extending the application to explore the framework. Aside from spending time side-by-side with a seasoned expert, there may not be a better way to develop expertise than to jump in and start using the tool. See the References section at the end of this article for links to several sources that should provide a lot of help.
The Grails Community
The Grails framework has a very active user community. The mailing lists referenced at the end of this article are a great resource to tap in to. The development team is working hard to implement new features every week. The user community has contributed a whole lot to the Grails framework in the form of patches, plugins, and ideas. An active user community is a key component for an open source project to thrive, and the Grails framework has a very active user community.
The Future For Grails
The Grails development team has laid out a roadmap leading up to the release of Grails 1.0 later this year. Defining the criteria for a 1.0 release is not an especially simple task. What makes a 1.0 release? While Grails is currently at 0.4.2, there are already Grails applications in production using releases earlier than the current release, including several public facing sites.
Summary
This article has provided a broad stroke overview of some of the core capabilities provided by the Grails framework. There is much more detail to be covered.
Grails is a remarkably flexible framework while maintaining an ease of use that is unparalleled by other web application frameworks targeted for the JVM. Use the exercises in this article as a jump start with the Grails framework and have fun exploring the possibilities!
References
- [1] grails.org
- [2] Grails User Guide
- [3] Grails Mailing Lists
- [4] The Definitive Guide To Grails
- [5] Groovy
- [6] Groovy In Action
- [7] GroovyBlogs
- [8] AboutGroovy.com
Software Engineering Tech Trends (SETT) is a regular publication featuring emerging trends in software engineering.