Grails MVC Application
Grails is an opinionated Groovy framework for creating MVC applications. Prior to Grails 3, the opinion was strong enough to pigeonhole its future use. Upon Grails 3, the Grails development team decided it was best to build Grails off of Spring Boot. This now opened Grails up to the full Spring Boot ecosystem.
Before you start this lesson, please meet the Installation Requirements of SDKMAN
Installation of Grails 3
Java 8
First thing before installing Grails 3 is to make sure you have Java 8. To install Java 8, from the terminal, query sdkman to find what version you have installed.
sdk list java
Each version of Java you have installed will have an *
next to it. The default version of Java will have a >
to the left of the side of the *
. If you do not have a version of Java 8 installed, type in the terminal
sdk use java 8u131
Your micro version of Java may differ and that is fine. You need to use Java 8. The early release of Java 9 currently does not work in Grails 3.
Now that you have Java 8 installed, set it to the default, again, updating the micro version as needed.
sdk default java 8u131
Groovy
While Java is a great language, Groovy provides us a lot of ease of use. Groovy, like Java, uses the JVM to run. Since Grails 3 is built on Spring Boot and Spring Boot uses Java, both Java and Groovy are supported. We will use Groovy, but also depend on Java. Hence, you also need to install Groovy.
sdk list groovy
At the time of this writing, Groovy 2.4.9 was the latest. We will install that.
sdk use groovy 2.4.9
Again, once installed, and like Java 8, make it the default
sdk default groovy 2.4.9
Grails 3
Now that we have Java and Groovy installed, let's follow that same pattern to install Grails 3
sdk list grails
At the time of this writing, Grails 3.2.9 was the latest version. Let us install that
sdk use grails 3.2.9
And again, make it default
sdk default grails 3.2.9
Creating a Grails 3 Application
For our demo application we will simply create an Address Book. Our Address Book requires a Person
, an Address
, and a PhoneNumber
. We will see how we can quickly create a MVC application using grails command line tools to auto build our domain models, services, and controllers. But before we do that, we actually have to create the application. If you are familiar with Ruby on Rails, SailsJS, or etc, this will feel very similar.
To create our application, we simply need to navigate in our computer to where we want the project, and from the terminal type
grails create-app addressbook
Just like RoR, SailJs, and the others, that one command bootstraps a working application. To see it run, type the following into your terminal and navigate to your browser at port 8080.
cd addressbook
grails dev run-app
Here, we are running in dev
, or development mode. We will cover why later, but for now, make sure to pass that argument. A word of note, whenever you update your source code, grails will recompile the application for you. If you are updating configuration, you will need to restart the server with the above command.
When you navigate to the application through the browser, you should see the following
This mean the Grails application is running and ready for us to add features. You should notice in the bottom left of the screen is a list of Available Controllers
. Since we have not added any controllers, this list is empty. Before we start adding controllers, let's first look at the file structure. Understanding how Grails is opinionated will help to rapidly produce working applicaitons.
The grails-app Directory
The most important directory automatically created for you is the grails-app
directory. Inside this directory we find our core features that make this a framework. Since Grails was originally designed to build MVC patterns, you naturally find directories mapping to the MVC relationship
The controllers Directory
This maps to the C
part of MVC. This should be fairly obvious. Controllers are what allow our application to request data from a model and pass that data to the view for rendering.
The domain Directory
The domain directory is our M
in MVC. It represents the models used in the application. By using Gorm, we will be able to persist our data easily to a database as well as query when required.
The services Directory
Controllers should be lightweight and easy to follow. Because sometimes we find ourselves having to manipulate data, the services directory provides an opinionated location to encapsulate that work.
The views Directory
Since our applications will only produce and consume JSON, we will never be concerned about rendering views, and hence, not cover them here in this book. This follows for the assets and taglib directories. Our JavaScript, images, etc, are all hosted on a CDN.
The conf Directory
Similar to a Spring Boot application's resources
directory, any configuration files pertaining to Grails will be housed inside this directory. By default, Grails provides application.yaml
and logback.groovy
configurations as well as a spring
directory to house beans.
The init Directory
This directory houses the Application.groovy
file which has our application's main
method. It also provides use with an automatically called Bootstrap.groovy
file which is used in starting and tearing down the application. You may find this file useful when you need to do some runtime configurations.
The src Directory
Because Grails 3 is Spring Boot, you have a src
path. At this time, we have not found a need to use this path beyond providing the test root for the application.
Application Files
Grails provides a series of files to allow the application to run. We shall briefly cover them here.
The build.gradle File
The build.gradle
file is the most important file of the bunch. It is the equivalent of the project object model (pom.xml) file found in Maven projects.
The gradle.properties File
This file houses the versions of Grails, Gorm, and the Gradle Wrapper. All the version need to match the environment and included gradle-wrapper.jar
found in the project.
Grails create-app Summary
You can tell that Grails, just like RoR, SailsJS, etc, does the heavy lifting of setting up a project for you with the create-app
command. Of course this command just gets us running. We will need to make small changes to suit our current project as it unfolds. Use the grails create-app
command to quickly start building out a new microservice.
Modifying our Default Configuration
By default, Grails 3 comes with logging set to ERROR
. If you want to change the level of logging shown to include INFO
or higher, modify grails-app/conf/logback.groovy
so that the last line looks as follows.
root(INFO, ['STDOUT'])
Adding domains to our application
Since we use Grails to write services that involve persistency, it wouldn't make much sense to build out other features first. In our application we have 3 domain models, Person
, Address
, and PhoneNumber
. Let's create each one now.
Person Domain
To create a domain, we again will use Grails built-in tools. To create our Person domain, simply type
grails create-domain-class Person
This will create a Person
class under domains/addressbook
. When you open this, you will see the schema is blank. Let's add some basic properties.
Tip: It is smart to use objects as datatypes instead of primitives (e.g. long id
) because primitives are not nullable.
Our person should have an id
and a name
. The dateCreated
and lastUpdated
are automatically populated for you if and only if you add them as properties.
Address Domain
Next, we need to also create an address for a person. Because it makes sense that a person may have more than one address, we shall make this a has-many
relationship, but first, let's just create the Address
.
grails create-domain-class Address
Once Grails finishes up, open the Address.groovy
and add the following properties.
For this class we give the standard lastUpdated
and dateCreated
properties, as well as provide an id
and an address
. While address
here is just a String
, and one may argue we should break that down into atomic parts, the goal here is only to demonstrate the hasMany
relationship. As you can see, in this class we added
static belongsTo = [person: Person]
This states that the Address
has a foreign relationship to Person
. Person
will need to be updated to reflect that relationship as well.
PhoneNumber Domain
We will mimic the Address domain but relate this to phone numbers. In your terminal type the following:
grails create-domain-class PhoneNumber
And then update the PhoneNumber
domain class to match the following
Because the PhoneNumber
belongs to a Person
, and the Person
may have many PhoneNumber
, we also need to update the relationship map in Person
as follows:
static hasMany = [addresses: Address, phoneNumbers: PhoneNumber]
Domain Constraints
Domain constraints allow us to validate the model before persisting. In our simple demo we are not concerned about this at the moment. The Grails 3 support material provided does cover this is good detail.
Adding controllers to our application
Since we will eventually be migrating to Camel to handle our routes in our application, for this demo, we do not need to worry about how the routes are built. Instead we will use Grails scaffolding to build this out of us. But we do need to make controllers for each Domain Model we want to be able to access. So let's start with creating the PersonController
.
grails create-controller PersonController
Once complete, under controllers/addressbook
we will see PersonController.groovy
. Open that file and replace the contents of the class with
class PersonController {
static scaffold = Person
}
This will link the Person
Domain Model to the controller and tell Grails on start up to automatically build the UI and RESTful endpoints for PersonController
. When restarted, Grails will link the new controller under Available Controllers
. You should have also noticed from the terminal output that Grails also create src/test/groovy/addressbook/PersonControllerSpec
. Grails assumes you will test with Spock and stub out the test for you.
Continuing, we now can add both the AddressController
and the PhoneNumberController
.
grails create-controller AddressController
grails create-controller PhoneNumberController
And replace the classes contents with:
class AddressController {
static scaffold = Address
}
class PhoneNumberController {
static scaffold = PhoneNumber
}
Again, restarting the application will now link in both new controllers, but more importantly, you can build out our entire relationship now. While we typically would not use this in production, it does provide us with a set of development tools to easily work out any logic issues we may be having.
Adding Actuator-UI
Actuator-UI provides us a visual toolkit to analyze our application. While Actuator itself is installed by default when we create the application, the UI portion is not. To install it, add to the dependencies
closure in build.gradle
the following
dependencies {
...
...
...
compile 'org.grails.plugins:actuator-ui:1.1'
}
Then in grails-app/conf/application.yaml
, you will need to turn on jmx
# Spring Actuator Endpoints are Disabled by Default
endpoints:
enabled: true
jmx:
enabled: true
Restarting the application and looking at Available Controllers
once more and you will see the endpoint route to the dashboard provided.
Adding the Grails Console UI
The Grails Console itself is available by default, but if you wanted it as a browser UI, you can simply add to build.gradle
dependencies the following line
dependencies {
...
...
...
runtime 'org.grails.plugins:grails-console:2.0.8'
}
Upon restarting the application again, you will be presented with a new route in Available Controllers
. Following that route will provide you with a web based runtime console, allowing you access to the runtime to debug as needed.
Conclusion
This article provided a primer to building a very simple Grails 3 application. We did not consider controllers nor services in depth. If fact, we even didn't consider domain models too in-depth either. It was our intention to lead you to working through a full Grails MVC application with SaaS Industries software developers as the audience. Please contact your team lead for a digital Grails 3 book to use so you may now continue learning Grails at an in-depth level.