Introduction to Grails Christopher Bartling
May 17, 2015
Introduction to GrailsIntroduction to Grails
Christopher BartlingChristopher Bartling
TopicsTopics
Decomposing Grails
Major components
Extending Grails with plugins
Demostrations
Basic Grails commands
Book Club
Questions
Decomposing Grails
Major components
Extending Grails with plugins
Demostrations
Basic Grails commands
Book Club
Questions
What is Grails?What is Grails?
Next generation web framework for the JVM
Focus on developer productivity
Dynamic language - Groovy
Convention over Configuration
Pragmatic tooling promotes agility
DSLs, code generators, dependency resolution, multi-environment configuration
Next generation web framework for the JVM
Focus on developer productivity
Dynamic language - Groovy
Convention over Configuration
Pragmatic tooling promotes agility
DSLs, code generators, dependency resolution, multi-environment configuration
Under the hoodUnder the hood
Grails utilizes a lot of existing Java frameworks
Spring Framework: Dependency injection, AOP, core abstractions
Spring MVC: Web application framework
Hibernate: Relational database persistence
SiteMesh: Web layout and templating
Servlet API: Core web application infrastructure
Grails utilizes a lot of existing Java frameworks
Spring Framework: Dependency injection, AOP, core abstractions
Spring MVC: Web application framework
Hibernate: Relational database persistence
SiteMesh: Web layout and templating
Servlet API: Core web application infrastructure
Decomposing GrailsDecomposing Grails
Grails scripts and Gant
Model-View-Controller (MVC) design
Grails Object Relational Mapping (GORM)
Services
Dependency resolution and configuration
Plugins
Grails scripts and Gant
Model-View-Controller (MVC) design
Grails Object Relational Mapping (GORM)
Services
Dependency resolution and configuration
Plugins
Grails scriptsGrails scripts
Generate various parts of the Grails application
create-app: Creates a blank Grails application
create-domain-class: Creates a new domain object
generate-all: Generates the controller and associated views for a domain object
run-app: Runs the Grails application in the bundled Tomcat engine
Generate various parts of the Grails application
create-app: Creates a blank Grails application
create-domain-class: Creates a new domain object
generate-all: Generates the controller and associated views for a domain object
run-app: Runs the Grails application in the bundled Tomcat engine
GantGant
Grails build system
Thin DSL wrapper around Apache Ant
Gant scripts reside in grails-app/scripts directory
Create a new script:
grails create-script [scriptName]
Grails build system
Thin DSL wrapper around Apache Ant
Gant scripts reside in grails-app/scripts directory
Create a new script:
grails create-script [scriptName]
Domain objects (Model)Domain objects (Model)
Automatically mapped to database schema
Can tweak mapping through DSL on domain class
Object relationship management
DSL on domain class
Attribute and object validation
Configured through DSL on domain class
Automatically mapped to database schema
Can tweak mapping through DSL on domain class
Object relationship management
DSL on domain class
Attribute and object validation
Configured through DSL on domain class
Domain class exampleDomain class example
class Book {
String title
String author
String description
Date reviewDate
static hasMany = [comments: Comment]
static constraints = {
title nullable: false, blank: false, size: 1..1024
author nullable: false, blank: false, size: 2..255
description nullable:true, blank: true, maxSize: 1000000
reviewDate nullable: true
}
}
class Book {
String title
String author
String description
Date reviewDate
static hasMany = [comments: Comment]
static constraints = {
title nullable: false, blank: false, size: 1..1024
author nullable: false, blank: false, size: 2..255
description nullable:true, blank: true, maxSize: 1000000
reviewDate nullable: true
}
}
GORMGORM
The default Grails persistence layer
Functionality for reading, listing, sorting, counting, saving, and deleting objects
Relationship management
Dynamic finder and counting methods
Criteria, HQL, and SQL queries
Pagination support
The default Grails persistence layer
Functionality for reading, listing, sorting, counting, saving, and deleting objects
Relationship management
Dynamic finder and counting methods
Criteria, HQL, and SQL queries
Pagination support
Domain class dynamic runtime methodsDomain class dynamic runtime methods
Groovy provides method interception support
Grails injects several methods on all domain objects at runtime
get(id), getAll([id, id, id, …]), list(), listOrderBy*()
findBy*(), findAllBy*(), count(), countBy*()
save(), delete(), validate(), hasErrors
withTransaction, withCriteria
Groovy provides method interception support
Grails injects several methods on all domain objects at runtime
get(id), getAll([id, id, id, …]), list(), listOrderBy*()
findBy*(), findAllBy*(), count(), countBy*()
save(), delete(), validate(), hasErrors
withTransaction, withCriteria
Synthesized domain methodsSynthesized domain methods
The countBy*() and findBy*() methods are synthesized from domain class properties and the following comparators:
Equal, NotEqual, LessThan, LessThanEquals, GreaterThan, GreaterThanEquals, Like, like (case insensitive), InList, Between, IsNull, IsNotNull
This support works for up to two properties with optional comparators and logical operator
The countBy*() and findBy*() methods are synthesized from domain class properties and the following comparators:
Equal, NotEqual, LessThan, LessThanEquals, GreaterThan, GreaterThanEquals, Like, like (case insensitive), InList, Between, IsNull, IsNotNull
This support works for up to two properties with optional comparators and logical operator
Domain class constraint validationDomain class constraint validation
The domain class’s save() and validate() methods will trigger data validation
Domain object maintains validation errors collection
17 built-in constraints
The validator constraint supports custom validation scenarios
Many of the domain constraints influence database schema generation
The domain class’s save() and validate() methods will trigger data validation
Domain object maintains validation errors collection
17 built-in constraints
The validator constraint supports custom validation scenarios
Many of the domain constraints influence database schema generation
Domain classes: One-to-one relationshipsDomain classes: One-to-one relationships
One class references another
Declared by a property of the type of referenced domain class
Bi-directional one-to-one: Each class has a property to the other domain class
Ownership and cascading updates are declared with the static belongsTo property
One class references another
Declared by a property of the type of referenced domain class
Bi-directional one-to-one: Each class has a property to the other domain class
Ownership and cascading updates are declared with the static belongsTo property
Domain classes: One-to-many relationshipsDomain classes: One-to-many relationships
Uni-directional one-to-many relationship uses the static hasMany property
The static belongsTo property can also be used in this relationship scenario
Bi-directional one-to-many relationship is as easy as adding a reference for the parent object reference and using the static belongsTo property
Uni-directional one-to-many relationship uses the static hasMany property
The static belongsTo property can also be used in this relationship scenario
Bi-directional one-to-many relationship is as easy as adding a reference for the parent object reference and using the static belongsTo property
Domain classes: Many-to-many relationshipsDomain classes: Many-to-many relationships
Declared by adding a static hasMany property to each class participating in the relationship
One of the classes must declare a static belongsTo property to properly set ownership of the relationship
Declared by adding a static hasMany property to each class participating in the relationship
One of the classes must declare a static belongsTo property to properly set ownership of the relationship
ControllersControllers
Groovy class with name ending in “Controller”
Resides in grails-app/controllers directory
Dynamically receive methods and properties at runtime
Any closure defined as a property of the controller becomes an action reachable by URL
book-club/book/add
Groovy class with name ending in “Controller”
Resides in grails-app/controllers directory
Dynamically receive methods and properties at runtime
Any closure defined as a property of the controller becomes an action reachable by URL
book-club/book/add
Controller responsesController responses
Return a map of data or nothing
Controller forwards execution control to view of the same name as action
Redirect to another action or URL
Render output directly
Rendering can be a view, template, JSON, XML, binary
JSON and XML converters part of Grails
Return a map of data or nothing
Controller forwards execution control to view of the same name as action
Redirect to another action or URL
Render output directly
Rendering can be a view, template, JSON, XML, binary
JSON and XML converters part of Grails
UrlMappings.groovyUrlMappings.groovy
Resides in grails-app/conf directory
DSL for customizing the mapping of the URIs to controller actions
Use this file to implement RESTful web service URIs
Error status codes can also be mapped to custom error pages
Resides in grails-app/conf directory
DSL for customizing the mapping of the URIs to controller actions
Use this file to implement RESTful web service URIs
Error status codes can also be mapped to custom error pages
ViewsViews
Each controller will have a corresponding directory under grails-app/views for views
e.g. grails-app/views/book
Groovy Server Pages (GSPs) reside here
View rendering convention: Forward to view GSP named the same as controller action
This is very customizable
Each controller will have a corresponding directory under grails-app/views for views
e.g. grails-app/views/book
Groovy Server Pages (GSPs) reside here
View rendering convention: Forward to view GSP named the same as controller action
This is very customizable
Groovy Server Pages (GSPs)Groovy Server Pages (GSPs)
View rendering
Reside in the grails-app/views directory
Grails provides about 50 tags for use in GSPs
Logical, looping, link creation, forms and form inputs, JavaScript and other resource management tags
Custom taglibs are easily created for use in GSPs
View rendering
Reside in the grails-app/views directory
Grails provides about 50 tags for use in GSPs
Logical, looping, link creation, forms and form inputs, JavaScript and other resource management tags
Custom taglibs are easily created for use in GSPs
Tag librariesTag libraries
Reside in grails-app/taglib directory
Groovy class with name ending in “TagLib”
Taglib actions are just closure properties
Write output to OutputStream out
Automatically injected into your taglib instance
TagLib attributes become attributes on taglib XML
Reside in grails-app/taglib directory
Groovy class with name ending in “TagLib”
Taglib actions are just closure properties
Write output to OutputStream out
Automatically injected into your taglib instance
TagLib attributes become attributes on taglib XML
SiteMeshSiteMesh
Web page layout and decorator framework
Uses HTML meta tags to decorate your web page with standardized layout
Implemented as a page filter
Layout reside in grails-app/views/layouts
The main.gsp is your default layout master page
Web page layout and decorator framework
Uses HTML meta tags to decorate your web page with standardized layout
Implemented as a page filter
Layout reside in grails-app/views/layouts
The main.gsp is your default layout master page
ServicesServices
Reside in grails-app/services directory
Automatically have transaction support
static transactional = true | false
Automatically hosted by Spring DI container as singleton-scoped beans by default
Services can be injected into controllers, other services, domain classes
Reside in grails-app/services directory
Automatically have transaction support
static transactional = true | false
Automatically hosted by Spring DI container as singleton-scoped beans by default
Services can be injected into controllers, other services, domain classes
Dependency resolutionDependency resolution
Spring Framework is used to provide dependency injection
Spring bean configuration in resources.groovy
Spring DSL
Services will be autowired in controllers automatically
Spring Framework is used to provide dependency injection
Spring bean configuration in resources.groovy
Spring DSL
Services will be autowired in controllers automatically
Extending Grails with pluginsExtending Grails with plugins
At its heart, Grails is really just a plugin management system
Most of the major pieces of Grails are implemented as plugins
• http://grails.org/plugins/ hosts Grails plugins
• Currently about 575 plugins available!
• One of Grails big selling points
At its heart, Grails is really just a plugin management system
Most of the major pieces of Grails are implemented as plugins
• http://grails.org/plugins/ hosts Grails plugins
• Currently about 575 plugins available!
• One of Grails big selling points
Finding and installing Grails pluginsFinding and installing Grails plugins
• Listing plug-ins
• grails list-plugins
• Installing a plugin
• grails install-plugin [plugin-name] [version]
• Grails takes care of downloading, installing, and managing the plugin
• Listing plug-ins
• grails list-plugins
• Installing a plugin
• grails install-plugin [plugin-name] [version]
• Grails takes care of downloading, installing, and managing the plugin
Testing in GrailsTesting in Grails
• Grails creates unit test stubs
• Several GroovyTestCase subclasses specialized for testing Grails components
• Great mock object support
• mockDomain, mockForConstraintsTest, mockController, mockTagLib, mockLogging
• Integration testing supported with separate test environment configuration
• Grails creates unit test stubs
• Several GroovyTestCase subclasses specialized for testing Grails components
• Great mock object support
• mockDomain, mockForConstraintsTest, mockController, mockTagLib, mockLogging
• Integration testing supported with separate test environment configuration
Grails demonstrationsGrails demonstrations
Questions?Questions?
Resources available onlineResources available online
• Presentation and demo available on BitBucket.org
• https://bitbucket.org/cebartling/presentations
• Need Mercurial client to clone the repository or pull a zip archive snapshot of the repository
• Presentation and demo available on BitBucket.org
• https://bitbucket.org/cebartling/presentations
• Need Mercurial client to clone the repository or pull a zip archive snapshot of the repository
Contact informationContact information
• Christopher Bartling
• Twitter: @cbartling
• Blog: http://bartling.blogspot.com
• Christopher Bartling
• Twitter: @cbartling
• Blog: http://bartling.blogspot.com