Grails 101

24
Grails High-velocity development for Spring applications

Transcript of Grails 101

Page 1: Grails 101

GrailsHigh-velocity development for Spring applications

Page 2: Grails 101

About MeDavid Jacobs● Web Developer since '98● Groovy since '06● Grails focus in '08-'09

Twitter@MetaThis

Page 3: Grails 101

What is Grails?Grails is an open-source framework for high-velocity development of Spring applications● Sensible defaults● Convention-over-configuration● DRY● Dynamic metaprogramming● End-to-end integrated stack● Enables you to focus on the business problem

Page 4: Grails 101

Best-of-Breed Java Technologies● Spring ● Spring MVC● Hibernate● log4j● jUnit● SiteMesh

Page 5: Grails 101

Integrated Stack● Layers and technologies integrated and wired

out-of-the-box● Default configurations based on industry best

practices● 80/20 rule

Page 6: Grails 101

Directory Structure● grails-app - top level directory for Groovy sources

● conf - Configuration sources.

● controller - Web controllers - The C in MVC.

● domain - The application domain.

● i18n - Support for internationalization (i18n).

● services - The service layer.

● taglib - Tag libraries.

● views - Groovy Server Pages.

● scripts - Gant/Gradle scripts.● src - Supporting sources

● groovy - Other Groovy sources

● java - Other Java sources

● test - Unit and integration test

Page 7: Grails 101

GORM● Object Relational Mapping (ORM)● Data access layer● Simplifies configuration through conventions● Defaults to Hibernate implementation

● Provided as plugin, alternatives pluggable● Extends and simplifies data access APIs● Similar to ActiveRecord in Rails

Page 8: Grails 101

GORMDomain Modeling

//this is a complete Hibernate mapping!class Employee { String firstName String lastName Date startDate}

Page 9: Grails 101

GORMDynamic CRUD

def employee = Employee.get(1)employee.delete()def newEmployee = new Employee(firstName: “Joe”, lastName: ”Programmer”)newEmployee.save()

Page 10: Grails 101

GORMDynamic finders

Employee.findByLastNameAndHireDateGreaterThan(“Jones”, someDate)

findBy and findAllBy● InList - In the list of given values● LessThan - less than the given value● LessThanEquals - less than or equal a give value● GreaterThan - greater than a given value● GreaterThanEquals - greater than or equal a given value● Like - Equivalent to a SQL like expression● Ilike - Similar to a Like, except case insensitive● NotEqual - Negates equality● Between - Between two values (requires two arguments)● IsNotNull - Not a null value (doesn't require an argument)● IsNull - Is a null value (doesn't require an argument)

Page 11: Grails 101

GORMHibernate HQL

Employee.findAll("from Employee as e where e.lastName like :lastName", [lastName:"Jon%"])

//with pagination and sortingEmployee.findAll("from Employee as e where e.lastName like :lastName", [lastName:"Jon%", max:10, offset:20, sort:"hireDate", order:"asc"])

Page 12: Grails 101

GORMSimplified Hibernate Criteria API

// Find incomplete tasks assigned to Jones where the company is Monsanto// and the project name begins with “Rubic”, order by task namedef criteria = Tasks.createCriteria()def tasks = criteria.list { eq(‘completed’, false) project{ like(‘name’ ‘Rubic%’) company{ eq(‘name’, ‘Monsanto’) } assignedEmployees{ eq(‘lastName’, ‘Jones’) } } order(‘taskName’, ‘asc’)}

Page 13: Grails 101

Web Layer● Controllers built on Spring MVC● URL mapping conventions map requests to controllers● Naming and directory conventions map actions to views● Built-in AOP action interceptors

● Every controller provides a beforeInterceptor and afterInterceptor● Specifiable by action, optionally with patterns and exclusions

● Servlet objects and convenience extensions injected into controller actions at runtime and provided as implicit variables

● servletContext, session, request, response, params, flash

Page 14: Grails 101

Spring MVCRequest parameters parsed into multidimensional params map

● Easily accessed with powerful Groovy map support.

<!-- HTML form --><input type=”text” name=”userName” />//controller codedef userName = params.userName

<!-- HTML form with dot-notation for complex embedded objects --><input type=”text” name=”user.address.zipCode” /><input type=”text” name=”user.address.state” />//controller codedef zipCode = params.user.address.zipCodedef state = params.user.address.state

Page 15: Grails 101

Data Bindingdef save = { //bind params to new instance def user = new User(params)

//persist user.save()}

def update = { //get instance from database def user = User.get(params.id) //bind params user.properties = params user.save()}

Page 16: Grails 101

Request Format TransparencyGrails codecs (dynamic encode/decode methods) easily automap formats like XML and JSON to the params map.

<!-- XML request --><user> <id>42</id> <address> <zipCode>63122</zipCode> </address></user>

//transparent to the controller codedef zipCode = params.user.address.zipCodedef user = new User(params.user)

Easily create custom codecs to support specific requirements

Page 17: Grails 101

XML & JSON MarshallingGroovy's popular XML support+Grails builders and codecs +Convenience methods

def list = { render Project.list() as XML}

def list = { render Project.list() as JSON}

Page 18: Grails 101

Groovy Server Pages (GSP)● Similar to JSP

● Tag library like JSTL, but much more powerful● Easy custom tags● Powerful templates

● SiteMesh is automatically configured for layout management

Page 19: Grails 101

Groovy Server Pages (GSP)Tags

actionSubmitapplyLayoutcheckBoxcollectcookiecountrycountrySelectcreateLinkcreateLinkTocurrencySelectdatePickereacheachErrorelseelseif

fieldValuefindAllformformRemoteformatBooleanformatDateformatNumbergrephasErrorsheaderhiddenFieldifincludejavascriptjoin

layoutBodylayoutHeadlayoutTitlelinklocaleSelectmessagemetapagePropertypaginatepasswordFieldradioradioGroupremoteFieldremoteFunctionremoteLink

renderrenderErrorsresourceselectsetsortableColumnsubmitButtonsubmitToRemotetextAreatextFieldtimeZoneSelectunlessuploadFormwhile

Page 20: Grails 101

AJAX● Bundled with Prototype and Script.aculo.us● Excellent jQuery plugin● GSP tags for AJAX

● Adapters built-in for major JavaScript frameworks● Plugins provide additional AJAX functionality

Page 21: Grails 101

ConfigurationPer-Environment Configuration Supports SCM

● Package or run as any configured environment. Default environments and build configurations defined for development, test (staging) and production.

● Programmatic environment detection with provided Environment class.

environments { development { dataSource { dbCreate = "create-drop" // one of 'create', 'create-drop','update' url = "jdbc:hsqldb:mem:devDB" } }

test { dataSource { dbCreate = "update" url = "jdbc:hsqldb:mem:testDb" } }

production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } }}

Page 22: Grails 101

PluginsGrails extensions are provided as plugins

● Created by core Grails team and community● Powerful – a plugin IS a Grails application● Plugins typically bring the idioms of convention-over-configuration and simplified APIs to

popular libraries● Easy to create your own – provides a strong architecture for re-use across projects● Examples

● Spring Security● JMS● Spring WS● LDAP● Quartz

Page 23: Grails 101

PluginsPlugin development is very active

Page 24: Grails 101

The Bottom Line● Increases developer productivity● less code + less configuration = easier to maintain● Smaller learning curve than other Java web frameworks● Eases the learning curve for the underlying technologies● Project layout conventions and a standard technology stack promote quicker ramp-up time from one

Grails project to another● Increases agility potential through rapid proto-typing and quick customer feedback● Guides solid technology choices by providing excellent defaults● Developers enjoy it, which promotes morale and retention