Grails Cookbook - A collection of tutorials and examples

Grails 3 Project Structure Tutorial

If you are new to Grails development, this tutorial will discuss the structure of a Grails 3 application. There has been changes in the underlying technology behind Grails 3 and it would be a good start to understand the different sections, regardless if you have background to previous releases.

Although some things has changed, the rationale behind Grails is still the same. It is a framework that developers can use to develop applications quickly. It removes much of the pain so that developers can focus on writing code that have business value. The framework creates a ready to use structure where everything is wired beautifully and the architecture is ready for writing database-driven web application. It follows convention over configuration and many powerful features so that no time is wasted in preparing plumbing code.

For those new to Grails, we usually can start coding business logic without changing any configuration. Everything has default values and ready to fly. Of course we would need to change configuration later, but the point is the framework doesn't get in the way if we want to immediately be productive. Even the database configuration has default values that we can leave initially and just modify later.

Grails 3 is Now Based in Gradle

One big change in Grails 3 is that it is now using Gradle as build automation system. See that at the root folder there are files for Gradle support:

Personally, I believe that this is a big positive step toward the future. Most of open source Java frameworks and even commercial products are using Gradle or in the process of migrating to Gradle. It is the build system of the future and I that would be a good thing. Developers will have easy time jumping to different projects because of the familiarity with a common build system.

If you are unfamiliar with Gradle, the most important thing to note is that we can use this to manage our dependencies. If you need to integrate a third party Java library or a Grails plugin, we would need to update build.gradle file at the root folder.


Just add an entry in the dependencies for the required Java library or Grails plugin. Gradle will automatically pull the required jars and integrate them into the project.

Aside from dependencies, we usually don't need to edit other parts of the build.gradle file.

The grails-app Folder

Most of the things that we will write will reside in the grails-app folder. This is where our Grails specific code will reside and it follows certain conventions.

Assets folder
This is where we will put most of our static files that we will refer in our HTML code. It will usually contain files for JavaScript, CSS, images, and others.

Note that by default, Grails 3 application has a web design that we can use. The files shown above are for the built-in web design. We can change those to apply your own designs. But for those who are in a hurry (e.g. demo or simple school project), then there is no problem leaving the default design as is.
Conf folder
The conf folder is where the configuration files resides.
  • resources.groovy - Grails sits on top of the Spring framework. If we wish to define additional Spring objects, we can put it here. In my personal projects, I usually don't put anything here.
  • application.yml - This is the main configuration file and most of the settings goes here. The most common is the database config: Other config also goes here, even those coming from plugins are configured here also.
  • logback.groovy - This is the configuration file for logging.
Controllers folder
The controllers folder contains controller classes. If we need to create controllers, the corresponding classes generated will go here:

By default, UrlMappings.groovy is also created in this folder. This is the file where we can control how requests, depending on url format, direct to which controller or resource.

The default contents of UrlMappings.groovy is usually good as is without modification. But I will discuss later how to use this for custom purposes.
i8n folder
This is the folder that contains resources for translation. By default, lookups to messages are searched in messages.properties. But when users of your application has chosen a different locale, then lookups will automatically search the appropriate file. E.g. messages_ja.properties for Japanese.

I purposedly removed some of the i8n files to make the screenshot more concise. But by default, Grails 3 creates 17 resources corresponding to 17 different locales.
Init folder
This contains files related to when your application is launched. Application.groovy is a convenience class that we can use inside an IDE to launch our Grails 3 application. Because IDE's usually has a way to run a program that has a main static method. Hence this class is provided to launch our application via main method.

Bootstrap.groovy is where we can put initialization code when our Grails application starts up. For example, we can place code here to insert background data to the database that our web application will expect to be there. We can use GORM code here as GORM is already loaded when this is invoked.

Views folder
The views folder contains GSP files. This is the equivalent of Java's JSP files in Grails framework. This is where we put HTML related code to be rendered and shown to users.

Each controller (E.g. HelloController.groovy) will have a corresponding folder with the same name (without the controller suffix and the first letter is not capitalized). There is a special folder named layouts where templates are placed.

Templates are special GSP files that we can use to avoid repetitive code. This is where we will place our web design layout. The important thing is it should contain the <g:layoutBody/> tag.


Our individual views can then just specify which template to use via meta tag where name="layout". Since we specify main as the value, it will lookup main.gsp. The code inside our <body> tags will replace the <g:layoutBody/> section in the layout.

Domain folder

This is where we will put Groovy classes that corresponds to a table in a database. Here is a simple example of a domain class

package com.mydomain.myapp
class Person {
    String firstName
    String lastName
    Date dateOfBirth
    double salary
}

Services folder

Controllers are the entry point of interaction with users. But it is not good practice to put business code inside controllers. We usually place them in services, and we invoke those services inside controllers. Here is a simple service code:

package com.mydomain.myapp
class StudentService {
  Student createStudent(String lastName, String firstName) {
    Student student = new Student()
    student.lastName = lastName
    student.firstName = firstName
    student.referenceNumber = generateReferenceNumber()
    student.save()
    return student
  }
  private String generateReferenceNumber() {
    // some specific logic for generating reference number
    return referenceNumber
  }
}

So our controllers can invoke studentService.createStudent, and the details are hidden from the caller.
Taglib folder
One of my favorite thing in Grails is how easy it is to create a custom tag. This folder is where we place code for custom tags. Here is a simple example of a custom tag class:
package com.mydomain.myapp
class MySampleTagLib  {
  static namespace = "my"
  def greet = { attrs ->
    def name = attrs.name
	out << "Hello ${name}"
  }
}

And we can use this in our GSP code like this

<my:greet name="John"/>

And it will render:
Hello John
I find this very useful to compress my GSP codes. I write many custom tags to hide away specifics of web design and have my JSP code as small as possible LOC wise.

Source Folder

The source folder contains supporting code that we can use in our Grails project:

  • integration-test - this will contain integration test codes
  • main/groovy - we can write any Groovy classes here that we can use inside controllers, etc. E.g. utility classes.
  • test - this will contain unit test codes

Notes

The skeleton of a Grails 3 application is intuitive and easy to understand, specially for those with experience building web applications in Java. But for those unfamiliar, more post will come to discuss and give examples on the sections listed above.