5. What is Grails?
• A full stack web framework
• Open Source (Apache 2.0 license)
• Based on Groovy
• Fully compatible with Java
1.0 1.1.1
Release Release
2005 2006 02/2008 11/2008 2009
5
6. Architecture
Grails
Groovy
Java EE Spring Hibernate SiteMesh
The Java Development Kit
The Java Language (JDK)
The Java Virtual Machine
6
7. Design Goals / NYAJWF
Full Stack
Productivity Convention /
Configuration
Grails Agile
Community Philosophy
Java Solid
Integration Foundations
7
8. Design Goals / NYAJWF
• Full stack
• Grails comes with a full development
environment
• Web server (Jetty / Tomcat)
• Database (HSQLDB)
• Testing (JUnit)
• Command line shell
• Grails console
8
9. Design Goals / NYAJWF
• Convention / Configuration
• Sensible defaults based on source code
• Defaults can be overriden with no XML
• Existing XML configurations can still be used
9
10. Design Goals / NYAJWF
• Agile philosophy
• Development is an interactive process
• Add / modify Controllers, Domains and Views
while application is running
• Refresh view to test results
• Zero turn-around
• No deployment / server restart required
• Rapid prototyping
• Scaffolding
10
11. Design Goals / NYAJWF
• Solid foundations
• Built on tested and proven OS technologies
• Spring framework
• Hibernate ORM
• SiteMesh page layout framework
• AJAX libraries: script.aculo.us, Rico, prototype
• HSQLDB
• Junit
• Minimizes learning curve
• Backed up by SpringSource
11
12. Design Goals / NYAJWF
• Java Integration
• Groovy code is compiled to bytecode
• Java code can be run as Groovy*
• GDK -> Groovy’s extention to JDK (~ 60
enhanced classes)
• GroovyClassLoader
• Loads and parses Groovy classes to be used
in Java classes
12
19. Design Goals / NYAJWF
• Productivity
• Development is fun!
• Develop web applications much quicker
• Concentrate on business model
• Get instant feedback
• No XML configuration
• Ready to use development environment
19
29. Groovy 101
• OO dynamic programming language
• A superset of the Java language
• Works seamlessly with Java libraries
• Most Java Code is syntactically valid Groovy
• Compiled to JVM bytecode
• Used as a scripting language for the JVM
James Strachan's JSR 241
1.6.5 Release
Weblog 1.0 Release
2003 2007 2009
29
31. Groovy 101
• Differences from Java (partial list)
• GDK extends JDK (e.g. GString)
• Parenthesis and Semicolons are optional
• Implicit return, getters and setters
• Anonymous inner classes not supported
• == equality not identity
• Default access of “public”
• Only runtime exceptions
31
32. Groovy 101
• Features (very partial list…)
• Dynamic typing
• Closures
• Operator Overloading
• Native support for RegEx
• Native support for markup languages
• Native support for testing (JUnit)
• Expressions embedded inside strings
32
33. Dynamic Typing
• Use def keyword when defining variables
(optional)
• At runtime, the appropriate type will be
used based on assigned value
def var = 1
assert var.class in java.lang.Integer
var = “Hello World”
assert var.class in java.lang.String
33
34. Closures
• What is a closure?
• An anonymous block of code
• Do not have to be declared in a class
• An object of type groovy.lang.Closure
• Assigned to variables
• Passed as method arguments
• Can reference variables within their scope
• Executed when it’s called—not when it’s
defined
35
35. Closures
• Syntax
• Must be enclosed by curly braces “{ }”
• May take a list of optional arguments
separated by “,”
• The symbol “->” separates args from body
• “it” represents single arg (-> not required)
{ [optional args ->] zero or more statements }
36
39. Why Groovy?
• Example:
• Define Todo Class
• Create list public class Todo {
Todo.groovy
String name
• Add 3 todo’s }
String note
• Print List def todos = [
new Todo(name:"1", note:"one"),
new Todo(name:"2", note:"two"),
new Todo(name:"3", note:"three")
• Groovy: 12 LOC ]
todos.each {
println "${it.name} ${it.note}“
}
40
40. Why Groovy?
• Java: 45 LOC Todo.java
import java.util.List; public void setNote(String note) {
import java.util.ArrayList; this.note = note;
import java.util.Iterator; }
public static void main(String[] args){
public class Todo { List todos = new ArrayList();
private String name; todos.add(new Todo("1", "one"));
private String note; todos.add(new Todo("2", "two"));
public Todo() {} todos.add(new Todo("3","three"));
public Todo(String name, String note){
this.name = name; for(Iterator iter =
this.note = note; todos.iterator();iter.hasNext();){
} Todo todo = (Todo)iter.next();
public String getName() { System.out.println(todo.getName() +
return name; " " + todo.getNote());
} }
public void setName(String name) { }
this.name = name; }
}
public String getNote() {
return note;
}
41
49. GORM (Grails ORM)
• Simplifies data access
• Uses Groovy’s dynamic typing
• Injects CRUD methods into the domain class
• Provides dynamic finder methods
• Eliminates boiler plate code implementation
• No required inheritance from a persistent class
• Based on Hibernate 3
50
50. Basic Domain Creation
• Create a new domain class
app-dir> grails create-domain-class speaker
class Speaker {
static constraints = {
}
}
51
51. Basic Domain Creation
• Customize class
class Speaker {
String firstName
String lastName
String company
String title
static constraints = {
firstName(maxSize: 20)
lastName(maxSize:20)
title(maxSize:50)
} optimistic locking
}
52
53. Dynamic Finders
• Looks like a static method invocation
• methods do not exist in the code
• generated at runtime based on class properties
def spkr = Speaker.findByFirstName(“Jhon”)
def spkr = Speaker.findByFirstNameAndLastName(“Jhon”, “Smith”)
def spkrs = Speaker.findByAllFirstNameLike(“J%”)
def spkrs =
Book.findAllByTitleLike(“J%",
[max:3, offset:2, sort:"title", order:"desc"])
54
55. Controllers
• Handles requests
• Creates or prepares the response
• A new instance created for each request
• Default URL Mapping:
controller
params.id
name
/app-name/speaker/update/id
application action
name name
56
56. Controller Creation
• Create a new controller
app-dir> grails create-controller speaker
class SpeakerController {
def index = { }
def actionName = {
// do controller logic
// create model
return model
}
def defaultAction = “actionName"
}
57
57. Models and Views
• Returning the model
• a model is a map used by view to render
response
Explicit model map return
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
Controller properties used as model
class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
58
58. Models and Views
• Selecting the View
• implicit using conventions
• explicit using render
Implicit
class BookController {
def show = {
[ book : Book.get( params.id ) ]
}
}
/app-name/views/book/show.gsp
Explicit
class BookController {
def show = {
def map = [ book : Book.get( params.id ) ]
render(view:"display", model:map)
}
/app-name/views/book/display.gsp
59
59. Data Binding
• Binding Request Data to the Model
• Based on Spring’s binding
/book/save?book.title=The_Stand&author.name=Stephen_King
class BookController {
def save = {
def b = new Book(params[„book‟]) //implicit constructor
def a = new Author(params[„author‟]) //implicit constructor
a.addToBooks(b)
a.save()
}
def update = {
def b = Book.get(params.id)
b.properties = params
b.save()
}
}
60
61. GSP (Grails Server Pages)
• Similar to JSP and ASP
• A mix of markup and GSP tags
• Uses model passed from Controller to render view
• GSP pages reside in “/grails-app/views” directory
• Supports scripting of Groovy (discouraged)
• Supports GSP expressions within “${ }”
62
62. GSP Tags
• Built-in GSP tags
• start with g: prefix (no tag library imports)
• attributes can be expression or maps
• control flow operations like in JSTL
• Tags as method calls
• GSP tags can be called as methods from
controllers, tag libraries or GSP views
<img src="<g:resource dir="images" file="logo.jpg" />" />
<img src="${resource(dir:'images', file:'logo.jpg')}" />
def imageLocation = g.resource(dir:"images", file:"logo.jpg")
63
63. Templates
• By convention _<view name> is a template
• can be rendered from a view or controller
grails-app/views/book/_bookTemplate.gsp
<div class="book" id="${book?.id}">
<div>Title: ${book?.title}</div>
<div>Author: ${book?.author?.name}</div>
</div>
grails-app/views/book/list.gsp
<g:render template="bookTemplate" model="[book:myBook]" />
<g:render template="bookTemplate" var="book“
collection="${bookList}" />
64
64. Layouts
• Based on Sitemesh
• a web-page layout and decoration framework
• decorates response and applies a consistent L&F
• uses composite pattern
• Layouts are located in grails-app/views/layouts
Specifying a Layout in a Controller
grails-app/views/layouts/customer.gsp
class BookController {
static layout = 'customer'
}
65
65. Services
• A class that ends with the convention “Service”
• Re-use business logic across application
• Controllers should handle request flow and redirects
• Manages transaction demarcation
app-dir> grails create-service simple
class SimpleService {
boolean transactional = true
def serviceMethod() {
}
}
66
66. Dependency Injection
• Use the property name representation of a service to
inject it to a Controller / Domain class
• Based on Spring Framework's dependency injection
capability
class BookController {
def bookService //BookService
…
}
class Book {
…
def bookService //BookService
def buyBook() {
bookService.buyBook(this)
}
}
67
67. Scaffolding
• auto-generate a whole application for a given domain
class including
• GSP views
• Controller actions for CRUD operations
• Database schema
• uses introspection
• dynamic scaffolding is generated at runtime
• static scaffolding is generated in source code
class BookController {
def scaffold = true
}
68
68. Testing
• Unit tests
• Grails does not inject dynamic methods
• no DB support
• based on JUnit
• extends GrailsUnitTestCase
• provides mocking support (EasyMock): mock*()
• uses assert*()
app-dir> grails create-unit-test speaker
app-dir> grails test-app -unit speaker
69
69. Testing
• Integration tests
• executes inside a full Grails environment
• runs against a live database
• uses Mock versions of the servlet request,
response, and session
• transaction is rolled back at the end
• supports URL mappings
app-dir> grails create-integration-test speaker
app-dir> grails test-app speaker
70
71. Performance
• The bad
• Dynamic is slower than static
• Many abstraction layers
• The good
• Bottleneck is usually I/O not CPU
• JDK 7 (JSR 292)
• OpenJDK: Da Vinci Project
72
73. Google App Engine
• A platform for developing and hosting
web applications in Google-managed
data centers
• Virtualizes applications across multiple
servers and data centers (cloud computing)
beta 1.0 Release 1.2.7 Release
2007 2008 2009
74
74. Google App Engine
• Free up to a certain level of resources
• Fees are charged for additional storage,
bandwidth, CPU
• Supports: Python and JVM languages
(Java, Groovy, JRuby, Scala, Clojure)
75
75. Grails on AppEngine
• Groovy 1.6.1 runs on AppEngine
• Grails 1.1.1 adds official support
• Grails AppEngine Plugin
• Replaces Hibernate with JDO (soon JPA)
• Integrates with AppEngine dev environment
and deployment tools
76