SlideShare a Scribd company logo
Application architectures
in Grails
Peter Ledbrook
e: p.ledbrook@cacoethes.co.uk
t: @pledbrook
Wednesday, 11 September 13
Book Author
Wednesday, 11 September 13
We start with our domain classes using the usual hasMany, belongsTo etc.
Book AuthorDomain
Scaffolded
BookController
Scaffolded
AuthorController
Wednesday, 11 September 13
Create instant web UI with scaffolded controllers
Can be retained for administrative UI if secured by Spring Security, Shiro, etc.
Book AuthorDomain
Scaffolded
BookController
Scaffolded
AuthorController
LibraryService
LibraryController Views
Wednesday, 11 September 13
Build out proper UI using controller actions and views, utilising business logic in the services
Controllers stick to HTTP management
Thank you
Wednesday, 11 September 13
Some time left for questions...
Only joking
Wednesday, 11 September 13
Is it always the best
architecture?
Wednesday, 11 September 13
How many people are using it?
Book Author
Why do we start here?
Wednesday, 11 September 13
“The database is just a
detail that you don’t need
to figure out right away”
NO DB - May 2012
Robert “Uncle Bob” Martin
Wednesday, 11 September 13
Domain-driven Design
Wednesday, 11 September 13
Not the same as domain classes first
Model your domain first without integration concerns
It’s in operation at all stages of development, not just up-front
Reminded of a problem domain related to managing meetings and attendees - focused so
hard on the DB tables that the program logic was a dog’s breakfast.
Think Physics
Friction
Gravity
Wednesday, 11 September 13
from Wikmedia Commons
Wednesday, 11 September 13
We can use the model to calculate useful information, such as how long it takes for a ball to
roll down a hill
The model only includes significant complexity - ignores the rest
Formula 1 makes use of CFD because they need it at the bleeding edge
Remember: you’re
trying to solve a
business problem
Wednesday, 11 September 13
You need to understand the problem domain
The model needs to reflect that understanding
Gradle is a great example of a rich, evolving, and useful domain model
The Life Preserver
Domain
REST
Persistence
Messaging
Events
Courtesy of Simplicity Itself
Wednesday, 11 September 13
Note how persistence is treated as an integration point
Opens up novel approaches
Could use mybatis + Flyway instead of GORM for example
An example - reporting
ReportController ReportService
Jasper
Wednesday, 11 September 13
High volume transactional web site, optimised for write
Everything was OK at this point
An example - reporting
ReportController ReportService
Jasper + HTML reports with paging
Breakage!
Wednesday, 11 September 13
The logic for building reports was complex
Who is responsible for the paging? The HTML generation?
Where is the state kept? The service? A domain class?
An example - reporting
PublisherReport
HTTP
Request
Summary
Table 1
Table 2
...
Table N
It’s a command object!
Wednesday, 11 September 13
Let’s try again
The logic for building the report and pagination is in the PublisherReport class
An example - reporting
class ReportController {
def print(PublisherReport report) {
JasperRenderer.render report
}
def json(PublisherReport report) {
render report as JSON
}
...
}
Wednesday, 11 September 13
The controller is now very thin
The report can support parameters for sub-reports etc.
The domain model is embodied in the command object
CQRS
Wednesday, 11 September 13
C
Q
R
S
ommand
uery
esponsibility
egregation
Wednesday, 11 September 13
The writes use a different model from the reads
Will be coming back to this later
What is my domain?
Domain Model
HTTP Database
? ?
Wednesday, 11 September 13
Always ask yourself this question throughout life of project
And is it closer to the user’s perspective or the persistence model? Or neither?
Former argues for a model based on command objects, the latter based on domain classes.
Post content
Wednesday, 11 September 13
The command model is very simple: author + post content + date
Wednesday, 11 September 13
Query model much more complex
Multiple timelines
Conversation threads
Retweets
Wednesday, 11 September 13
So working from your domain first is a good thing
And remember that different contexts have potentially different views of the model, i.e. the
user/client, persistence, other system components
DDD doesn’t preclude the CRUD/service-based architecture
So what are the driving forces behind architecture beyond the model?
Rich clients
Wednesday, 11 September 13
We’re not talking Warren Buffet here
Things like GMail
Once upon a time...
Wednesday, 11 September 13
Flash
Wednesday, 11 September 13
Pretty (but often useless - or just pretty useless)
Java
Wednesday, 11 September 13
Remember applets?
Liked the approach (particularly WebStart) but not often used. The browser was a delivery
mechanism, not a platform
It’s all about the
Javascript!
AngularJS
Knockout.js
Backbone.js
Underscore.js
jQuery.js
Moustache
Wednesday, 11 September 13
The browser is now a platform for rich applications
But how do these impact the Grails app?
The whole process of building a page on each request goes out the window
Google I/O 2012
Android activations to date
400 million
Apple WWDC 2012
iOS devices sold to date
365 million
Wednesday, 11 September 13
Let’s not forget Firefox OS
Lots of people potentially hitting a site at any one time!
Typical Grails architecture may struggle to handle the load (OpenSessionInViewInterceptor,
transactions, GSPs, thread-per-request)
An aside
If the whole Java client thing had worked out, would
you use it for every web application you wrote?
Would you use it for Wikipedia?
Wednesday, 11 September 13
Before jumping onto the whole “single-page app” bandwagon, work out whether it’s
appropriate for your app
Shared templates
HandlebarsViewResolver
or
<hbt:render template="..."/>
GSP
Wednesday, 11 September 13
Not much to talk about on client architecture, but template reuse is something to think about
View resolver only makes sense if client-side templates are complete views
hbt is a fictitious tag namespace representing a plugin based on Handlebars for Java
AJAX + JSON endpoints
enabler for async
Wednesday, 11 September 13
Rich UIs don’t talk HTML - use JSON endpoints (aka “REST”)
Asset delivery via Resources or asset-pipeline plugins
More scope for asynchronicity, since no wait for full page update
Grails 2.3 introduces some nice features for REST
What’s the need for
SiteMesh & GSP then?
Wednesday, 11 September 13
Difficult to impossible to remove these currently
Grails 3 will finally extricate them, allowing you to remove them from your project
Aside 2
Don’t be afraid to use Ruby/Node.js tooling
Grunt
Bower
Yeoman
Compass/SASS
Wednesday, 11 September 13
If you go for a heavy Javascript UI, consider Ruby/Node.js tooling
Generally richer than Java-based tooling
Async
for scalability
Wednesday, 11 September 13
To solve the problem of dealing with large number of concurrent requests
Without adding lots more servers
Grails Promise API
import static grails.async.Promises.*
class ReportController {
def print(PublisherReport report) {
task {
// Expensive report creation here
}
}
...
}
Wednesday, 11 September 13
We can now return Promise instances from actions
The expensive task no longer blocks the request thread, but...
Controller
Request
Thread Pool
Worker
Thread Pool
HTTP
Request
Offload
Task
Return thread
Wednesday, 11 September 13
The request threads are now free, but burden is on worker thread pool
If all worker tasks are synchronous, have we gained scalability?
In cases where just a few URLs are blocking for long(ish) periods of time, yes (kind of)
But otherwise, now bottleneck is on worker thread pool
Make efficient use of
server resources
Wednesday, 11 September 13
Async all the way through - Grails Promises, GPars, messaging
Remember that some things are inherently synchronous (think Fibonacci)
Grails app
ReportController
TagService PostService
Remote
access
Wednesday, 11 September 13
NetFlix style model: coarse-grained, self-contained services/apps accessed from other apps
Usually via REST
Async controllers
import static grails.async.Promises.*
class ReportController {
def tagService
def postService
def home() {
tasks tags: tagService.tagsWithCount()
trends: tagService.trendingTags()
timeline: postService.timeline(
params.userId)
}
...
}
Wednesday, 11 September 13
tagService and postService are both async
The model values are evaluated in parallel
This is a PromiseMap - view rendered only when all map values evaluated
Async controllers
import static grails.async.Promises.*
class TagService {
def remoteTagService
def tagsWithCount() {
task {
remoteTagService.tagsWithCount()
}
}
...
}
Wednesday, 11 September 13
You can also use @DelegateAsync to create async version of synchronous service
Currently not Grails’ sweet spot due to the solution’s lightweight nature...
...perhaps makes sense with Grails 3?
Rich domain model +
Promises API/GPars?
Wednesday, 11 September 13
Fully async backend
A good domain model makes it easy to identify parallelisable work
No simple solutions though! Concurrency is still a tricky problem.
GPars supports
• Dataflow
• Communicating Sequential Processes (CSP)
• Actor model
Wednesday, 11 September 13
Messaging
Wednesday, 11 September 13
A common solution to concurrency and scale
MyObject TheirObject
call
Wednesday, 11 September 13
MyObject TheirObject
Router
Router
message
response response
message
Headers
Body
Wednesday, 11 September 13
Decoupling via messages
Encourages separation of concerns & responsibilities
MyObject OtherObject
Router
Router
message
message
response
response
Cloud
Wednesday, 11 September 13
Easy to change and move objects
Scales well (think Actor model of concurrency)
Internal External
JMS
RabbitMQ
Events
Spring Integration
Apache Camel
Wednesday, 11 September 13
Internal and external can be integrated
Events is a special case of messaging (which I look at next)
Spring Integration
MyController
MyService
message
DB Persister
SplitterJMS Twitter
A channel (pipe)
Message endpoint
Wednesday, 11 September 13
Based on Enterprise Integration Patterns (filters & pipes)
Many options for routing and transforming messages
Logging adapters and wire tapping for debug
Spring Integration Groovy DSL
def builder = new IntegrationBuilder()
def ic = builder.doWithSpringIntegration {
messageFlow("flow") {
filter { it == "World" }
transform(inputChannel: "transformerChannel") {
"Hello " + it
}
handle { println "**** $it ****" }
}
}
ic.send "flow.inputChannel", "World"
ic.send "transformerChannel", "Earth"
Wednesday, 11 September 13
Debugging
Code comprehension
Performance (kind of)
Wednesday, 11 September 13
Events
Wednesday, 11 September 13
Special case of messaging
Event bus - ApplicationContext
ApplicationContext
PluginService
publish
PluginUpdateService YourListener
GORM
Wednesday, 11 September 13
Event bus - ApplicationContext
class PluginService {
def publish(PluginDetails info) {
...
publishEvent(new PluginUpdateEvent(...))
}
}
class PluginUpdateService implements
ApplicationListener<PluginUpdateEvent> {
def onApplicationEvent(PluginUpdateEvent e) {
...
}
}
Wednesday, 11 September 13
with spring-events plugin
Immutable “mesages”
@groovy.transform.Immutable
class PluginUpdateEvent {
String name
String version
String group
...
}
Wednesday, 11 September 13
Event listeners on separate threads (from thread pool)
Event bus - (grails-)events
Event bus (Reactor)
PluginService
publish
PluginUpdateService YourListener
Wednesday, 11 September 13
Event bus - (grails-)events
Event bus (Reactor)
Browser
RabbitMQ (pending)
events-push plugin
Wednesday, 11 September 13
Event bus - (grails-)events
class PluginService {
def publish(PluginDetails info) {
...
event "pluginUpdate", info
}
}
class PluginUpdateService {
@Selector
def pluginUpdate(PluginDetails info) {
...
}
}
Wednesday, 11 September 13
with spring-events plugin
AppEvents.groovy
includes = ["push"]
doWithReactor = {
reactor("grailsReactor") {
ext "browser", ["pluginUpdate"]
}
}
Wednesday, 11 September 13
In grails-app/conf
Can control which events are propagated to the browser
The “push” include sets up a
Include grailsEvents.js
window.grailsEvents = new grails.Events(baseUrl)
grailsEvents.on("pluginUpdate", function(data) {
// do something
});
Wednesday, 11 September 13
A CQRS architecture
Updates
Views
Concurrency
via event bus
Store changes
Separate data stores
for queries
Wednesday, 11 September 13
Why? Updates and querying often have different data requirements.
For example, Lanyrd use Redis structured data support
All read databases can be rebuilt from master events DB
CQRS designed for scale
Plugin Architectures
App
Feature
plugin 1
Feature
plugin 2
Feature
plugin 3
Events/SI/Message broker
Wednesday, 11 September 13
So why use messages to interact between the plugins?
Plugin Architectures
App
Feature
plugin 1
Feature
plugin 2
Feature
plugin 3
Events/SI/Message broker
App 2
Wednesday, 11 September 13
Easy to separate out into apps deployed independently
Ultimately, think about
what you need...
Wednesday, 11 September 13
...don’t just go the
“standard” route
automatically
Wednesday, 11 September 13
Thank you
Wednesday, 11 September 13
Ad

More Related Content

What's hot (19)

Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Zach Lendon
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
Zach Lendon
 
GR8Conf 2011: Adopting Grails
GR8Conf 2011: Adopting GrailsGR8Conf 2011: Adopting Grails
GR8Conf 2011: Adopting Grails
GR8Conf
 
Headless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIsHeadless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIs
sparkfabrik
 
Introduction to Grails 2013
Introduction to Grails 2013Introduction to Grails 2013
Introduction to Grails 2013
Gavin Hogan
 
React, Flux and more (p1)
React, Flux and more (p1)React, Flux and more (p1)
React, Flux and more (p1)
tuanpa206
 
Demo on JavaFX
Demo on JavaFXDemo on JavaFX
Demo on JavaFX
Knoldus Inc.
 
React + Redux for Web Developers
React + Redux for Web DevelopersReact + Redux for Web Developers
React + Redux for Web Developers
Jamal Sinclair O'Garro
 
The Saga of JavaScript and TypeScript: Part 1
The Saga of JavaScript and TypeScript: Part 1The Saga of JavaScript and TypeScript: Part 1
The Saga of JavaScript and TypeScript: Part 1
Haci Murat Yaman
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016
Alvaro Sanchez-Mariscal
 
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
Srijan Technologies
 
Introducing spring
Introducing springIntroducing spring
Introducing spring
Ernesto Hernández Rodríguez
 
JAX 2013: Modern Architectures with Spring and JavaScript
JAX 2013: Modern Architectures with Spring and JavaScriptJAX 2013: Modern Architectures with Spring and JavaScript
JAX 2013: Modern Architectures with Spring and JavaScript
martinlippert
 
Dropwizard Spring - the perfect Java REST server stack
Dropwizard Spring - the perfect Java REST server stackDropwizard Spring - the perfect Java REST server stack
Dropwizard Spring - the perfect Java REST server stack
Jacek Furmankiewicz
 
From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0
VMware Tanzu
 
A Closer Look At React Native
A Closer Look At React NativeA Closer Look At React Native
A Closer Look At React Native
Ian Wang
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
Daniel Woods
 
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
chbornet
 
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
Fwdays
 
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Reconciling ReactJS as a View Layer Replacement (MidwestJS 2014)
Zach Lendon
 
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer ReplacementMidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
MidwestJS 2014 Reconciling ReactJS as a View Layer Replacement
Zach Lendon
 
GR8Conf 2011: Adopting Grails
GR8Conf 2011: Adopting GrailsGR8Conf 2011: Adopting Grails
GR8Conf 2011: Adopting Grails
GR8Conf
 
Headless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIsHeadless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIs
sparkfabrik
 
Introduction to Grails 2013
Introduction to Grails 2013Introduction to Grails 2013
Introduction to Grails 2013
Gavin Hogan
 
React, Flux and more (p1)
React, Flux and more (p1)React, Flux and more (p1)
React, Flux and more (p1)
tuanpa206
 
The Saga of JavaScript and TypeScript: Part 1
The Saga of JavaScript and TypeScript: Part 1The Saga of JavaScript and TypeScript: Part 1
The Saga of JavaScript and TypeScript: Part 1
Haci Murat Yaman
 
Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016Mastering Grails 3 Plugins - Greach 2016
Mastering Grails 3 Plugins - Greach 2016
Alvaro Sanchez-Mariscal
 
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
[Srijan Wednesday Webinar] How to Run Stateless and Stateful Services on K8S ...
Srijan Technologies
 
JAX 2013: Modern Architectures with Spring and JavaScript
JAX 2013: Modern Architectures with Spring and JavaScriptJAX 2013: Modern Architectures with Spring and JavaScript
JAX 2013: Modern Architectures with Spring and JavaScript
martinlippert
 
Dropwizard Spring - the perfect Java REST server stack
Dropwizard Spring - the perfect Java REST server stackDropwizard Spring - the perfect Java REST server stack
Dropwizard Spring - the perfect Java REST server stack
Jacek Furmankiewicz
 
From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0From Spring Framework 5.3 to 6.0
From Spring Framework 5.3 to 6.0
VMware Tanzu
 
A Closer Look At React Native
A Closer Look At React NativeA Closer Look At React Native
A Closer Look At React Native
Ian Wang
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
Daniel Woods
 
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
JHipster Conf 2018 : Connect your JHipster apps to the world of APIs with Ope...
chbornet
 
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
"Applied Enterprise Metaprogramming in JavaScript", Vladyslav Dukhin
Fwdays
 

Viewers also liked (20)

Introduction to Grails Framework
Introduction to Grails FrameworkIntroduction to Grails Framework
Introduction to Grails Framework
PT.JUG
 
Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-final
Stéphane Maldini
 
Ss2gx
Ss2gxSs2gx
Ss2gx
Stéphane Maldini
 
Grails Overview
Grails OverviewGrails Overview
Grails Overview
Christopher Bartling
 
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEABecoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Andrey Cheptsov
 
Grails Connecting to MySQL
Grails Connecting to MySQLGrails Connecting to MySQL
Grails Connecting to MySQL
ashishkirpan
 
Dynamic Languages
Dynamic LanguagesDynamic Languages
Dynamic Languages
Tugdual Grall
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.
Infinity
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
guest6e3bed
 
Introduction to Groovy and Grails
Introduction to Groovy and GrailsIntroduction to Groovy and Grails
Introduction to Groovy and Grails
Marco Pas
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
JS Bournival
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
Manav Prasad
 
Message Driven Architecture in Grails
Message Driven Architecture in GrailsMessage Driven Architecture in Grails
Message Driven Architecture in Grails
Daniel Woods
 
AppSync.org: open-source patterns and code for data synchronization in mobile...
AppSync.org: open-source patterns and code for data synchronization in mobile...AppSync.org: open-source patterns and code for data synchronization in mobile...
AppSync.org: open-source patterns and code for data synchronization in mobile...
Niko Nelissen
 
Reactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and GrailsReactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and Grails
Steve Pember
 
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Christopher Bartling
 
Our way to microservices
Our way to microservicesOur way to microservices
Our way to microservices
Andi Pangeran
 
Lost art of troubleshooting
Lost art of troubleshootingLost art of troubleshooting
Lost art of troubleshooting
Leon Fayer
 
Event-Driven Architecture (EDA)
Event-Driven Architecture (EDA)Event-Driven Architecture (EDA)
Event-Driven Architecture (EDA)
WSO2
 
jDays - Spring Boot under the Hood
jDays - Spring Boot under the HoodjDays - Spring Boot under the Hood
jDays - Spring Boot under the Hood
Nicolas Fränkel
 
Introduction to Grails Framework
Introduction to Grails FrameworkIntroduction to Grails Framework
Introduction to Grails Framework
PT.JUG
 
Reactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-finalReactor spring one2gx_2013_0902-final
Reactor spring one2gx_2013_0902-final
Stéphane Maldini
 
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEABecoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Becoming a Productive Groovy, Grails and Spring Developer with IntelliJ IDEA
Andrey Cheptsov
 
Grails Connecting to MySQL
Grails Connecting to MySQLGrails Connecting to MySQL
Grails Connecting to MySQL
ashishkirpan
 
Groovy presentation.
Groovy presentation.Groovy presentation.
Groovy presentation.
Infinity
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
guest6e3bed
 
Introduction to Groovy and Grails
Introduction to Groovy and GrailsIntroduction to Groovy and Grails
Introduction to Groovy and Grails
Marco Pas
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
JS Bournival
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
Manav Prasad
 
Message Driven Architecture in Grails
Message Driven Architecture in GrailsMessage Driven Architecture in Grails
Message Driven Architecture in Grails
Daniel Woods
 
AppSync.org: open-source patterns and code for data synchronization in mobile...
AppSync.org: open-source patterns and code for data synchronization in mobile...AppSync.org: open-source patterns and code for data synchronization in mobile...
AppSync.org: open-source patterns and code for data synchronization in mobile...
Niko Nelissen
 
Reactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and GrailsReactive Microservice Architecture with Groovy and Grails
Reactive Microservice Architecture with Groovy and Grails
Steve Pember
 
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Christopher Bartling
 
Our way to microservices
Our way to microservicesOur way to microservices
Our way to microservices
Andi Pangeran
 
Lost art of troubleshooting
Lost art of troubleshootingLost art of troubleshooting
Lost art of troubleshooting
Leon Fayer
 
Event-Driven Architecture (EDA)
Event-Driven Architecture (EDA)Event-Driven Architecture (EDA)
Event-Driven Architecture (EDA)
WSO2
 
jDays - Spring Boot under the Hood
jDays - Spring Boot under the HoodjDays - Spring Boot under the Hood
jDays - Spring Boot under the Hood
Nicolas Fränkel
 
Ad

Similar to Application Architectures in Grails (20)

Microservices and functional programming
Microservices and functional programmingMicroservices and functional programming
Microservices and functional programming
Michael Neale
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
Dierk König
 
Angular from Scratch
Angular from ScratchAngular from Scratch
Angular from Scratch
Christian Lilley
 
Backbone
BackboneBackbone
Backbone
Ynon Perek
 
Cors michael
Cors michaelCors michael
Cors michael
Michael Neale
 
Droidcon event 2015 Bangalore
Droidcon event 2015 BangaloreDroidcon event 2015 Bangalore
Droidcon event 2015 Bangalore
Nitesh Verma
 
Client Libraries (Rodhes, 2011)
Client Libraries (Rodhes, 2011)Client Libraries (Rodhes, 2011)
Client Libraries (Rodhes, 2011)
Fabio Simeoni
 
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
Xamarin
 
SpringOne Tour St. Louis - Serverless Spring
SpringOne Tour St. Louis - Serverless SpringSpringOne Tour St. Louis - Serverless Spring
SpringOne Tour St. Louis - Serverless Spring
VMware Tanzu
 
Pattern: PMML for Cascading and Hadoop
Pattern: PMML for Cascading and HadoopPattern: PMML for Cascading and Hadoop
Pattern: PMML for Cascading and Hadoop
Paco Nathan
 
Siebel CRM in Production - What Now?
Siebel CRM in Production - What  Now?Siebel CRM in Production - What  Now?
Siebel CRM in Production - What Now?
Frank
 
Chrome & Webkit overview
Chrome & Webkit overviewChrome & Webkit overview
Chrome & Webkit overview
Bin Chen
 
Cartoset
CartosetCartoset
Cartoset
Javier de la Torre
 
Ruby meetup 7_years_in_testing
Ruby meetup 7_years_in_testingRuby meetup 7_years_in_testing
Ruby meetup 7_years_in_testing
Digital Natives
 
Writing Applications at Cloud Scale
Writing Applications at Cloud ScaleWriting Applications at Cloud Scale
Writing Applications at Cloud Scale
Matt Ryan
 
Rackspace & Akamai vs. Amazon & CloudFront for a Django site
Rackspace & Akamai vs. Amazon & CloudFront for a Django siteRackspace & Akamai vs. Amazon & CloudFront for a Django site
Rackspace & Akamai vs. Amazon & CloudFront for a Django site
Sep Dehpour
 
Lasso context-elicitation-framework- demo
Lasso context-elicitation-framework- demoLasso context-elicitation-framework- demo
Lasso context-elicitation-framework- demo
Hermann Stern
 
Semantics Enriched Service Environments
Semantics Enriched Service EnvironmentsSemantics Enriched Service Environments
Semantics Enriched Service Environments
Karthik Gomadam
 
Oredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.jsOredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.js
Jesse Cravens
 
Javascript Client & Server Architectures
Javascript Client & Server ArchitecturesJavascript Client & Server Architectures
Javascript Client & Server Architectures
Pedro Melo Pereira
 
Microservices and functional programming
Microservices and functional programmingMicroservices and functional programming
Microservices and functional programming
Michael Neale
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
Dierk König
 
Droidcon event 2015 Bangalore
Droidcon event 2015 BangaloreDroidcon event 2015 Bangalore
Droidcon event 2015 Bangalore
Nitesh Verma
 
Client Libraries (Rodhes, 2011)
Client Libraries (Rodhes, 2011)Client Libraries (Rodhes, 2011)
Client Libraries (Rodhes, 2011)
Fabio Simeoni
 
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
GitHub halp app - Minimizing platform-specific code with MVVM - Justin Spahr-...
Xamarin
 
SpringOne Tour St. Louis - Serverless Spring
SpringOne Tour St. Louis - Serverless SpringSpringOne Tour St. Louis - Serverless Spring
SpringOne Tour St. Louis - Serverless Spring
VMware Tanzu
 
Pattern: PMML for Cascading and Hadoop
Pattern: PMML for Cascading and HadoopPattern: PMML for Cascading and Hadoop
Pattern: PMML for Cascading and Hadoop
Paco Nathan
 
Siebel CRM in Production - What Now?
Siebel CRM in Production - What  Now?Siebel CRM in Production - What  Now?
Siebel CRM in Production - What Now?
Frank
 
Chrome & Webkit overview
Chrome & Webkit overviewChrome & Webkit overview
Chrome & Webkit overview
Bin Chen
 
Ruby meetup 7_years_in_testing
Ruby meetup 7_years_in_testingRuby meetup 7_years_in_testing
Ruby meetup 7_years_in_testing
Digital Natives
 
Writing Applications at Cloud Scale
Writing Applications at Cloud ScaleWriting Applications at Cloud Scale
Writing Applications at Cloud Scale
Matt Ryan
 
Rackspace & Akamai vs. Amazon & CloudFront for a Django site
Rackspace & Akamai vs. Amazon & CloudFront for a Django siteRackspace & Akamai vs. Amazon & CloudFront for a Django site
Rackspace & Akamai vs. Amazon & CloudFront for a Django site
Sep Dehpour
 
Lasso context-elicitation-framework- demo
Lasso context-elicitation-framework- demoLasso context-elicitation-framework- demo
Lasso context-elicitation-framework- demo
Hermann Stern
 
Semantics Enriched Service Environments
Semantics Enriched Service EnvironmentsSemantics Enriched Service Environments
Semantics Enriched Service Environments
Karthik Gomadam
 
Oredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.jsOredev 2013: Building Web Apps with Ember.js
Oredev 2013: Building Web Apps with Ember.js
Jesse Cravens
 
Javascript Client & Server Architectures
Javascript Client & Server ArchitecturesJavascript Client & Server Architectures
Javascript Client & Server Architectures
Pedro Melo Pereira
 
Ad

More from Peter Ledbrook (11)

Why Gradle?
Why Gradle?Why Gradle?
Why Gradle?
Peter Ledbrook
 
Improving your Gradle builds
Improving your Gradle buildsImproving your Gradle builds
Improving your Gradle builds
Peter Ledbrook
 
Why your build matters
Why your build mattersWhy your build matters
Why your build matters
Peter Ledbrook
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
Peter Ledbrook
 
Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013
Peter Ledbrook
 
Groovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developersGroovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developers
Peter Ledbrook
 
Grails & the World of Tomorrow
Grails & the World of TomorrowGrails & the World of Tomorrow
Grails & the World of Tomorrow
Peter Ledbrook
 
Migrating to Cloud Foundry
Migrating to Cloud FoundryMigrating to Cloud Foundry
Migrating to Cloud Foundry
Peter Ledbrook
 
Grails 2.0 Update
Grails 2.0 UpdateGrails 2.0 Update
Grails 2.0 Update
Peter Ledbrook
 
Grails and the World of Tomorrow
Grails and the World of TomorrowGrails and the World of Tomorrow
Grails and the World of Tomorrow
Peter Ledbrook
 
Cloud Foundry for Java devs
Cloud Foundry for Java devsCloud Foundry for Java devs
Cloud Foundry for Java devs
Peter Ledbrook
 
Improving your Gradle builds
Improving your Gradle buildsImproving your Gradle builds
Improving your Gradle builds
Peter Ledbrook
 
Why your build matters
Why your build mattersWhy your build matters
Why your build matters
Peter Ledbrook
 
Groovy for Java Developers
Groovy for Java DevelopersGroovy for Java Developers
Groovy for Java Developers
Peter Ledbrook
 
Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013Open source-and-you-gr8conf-us-2013
Open source-and-you-gr8conf-us-2013
Peter Ledbrook
 
Groovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developersGroovy & Grails for Spring/Java developers
Groovy & Grails for Spring/Java developers
Peter Ledbrook
 
Grails & the World of Tomorrow
Grails & the World of TomorrowGrails & the World of Tomorrow
Grails & the World of Tomorrow
Peter Ledbrook
 
Migrating to Cloud Foundry
Migrating to Cloud FoundryMigrating to Cloud Foundry
Migrating to Cloud Foundry
Peter Ledbrook
 
Grails and the World of Tomorrow
Grails and the World of TomorrowGrails and the World of Tomorrow
Grails and the World of Tomorrow
Peter Ledbrook
 
Cloud Foundry for Java devs
Cloud Foundry for Java devsCloud Foundry for Java devs
Cloud Foundry for Java devs
Peter Ledbrook
 

Recently uploaded (20)

Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 

Application Architectures in Grails

  • 1. Application architectures in Grails Peter Ledbrook e: [email protected] t: @pledbrook Wednesday, 11 September 13
  • 2. Book Author Wednesday, 11 September 13 We start with our domain classes using the usual hasMany, belongsTo etc.
  • 3. Book AuthorDomain Scaffolded BookController Scaffolded AuthorController Wednesday, 11 September 13 Create instant web UI with scaffolded controllers Can be retained for administrative UI if secured by Spring Security, Shiro, etc.
  • 4. Book AuthorDomain Scaffolded BookController Scaffolded AuthorController LibraryService LibraryController Views Wednesday, 11 September 13 Build out proper UI using controller actions and views, utilising business logic in the services Controllers stick to HTTP management
  • 5. Thank you Wednesday, 11 September 13 Some time left for questions...
  • 7. Is it always the best architecture? Wednesday, 11 September 13 How many people are using it?
  • 8. Book Author Why do we start here? Wednesday, 11 September 13
  • 9. “The database is just a detail that you don’t need to figure out right away” NO DB - May 2012 Robert “Uncle Bob” Martin Wednesday, 11 September 13
  • 10. Domain-driven Design Wednesday, 11 September 13 Not the same as domain classes first Model your domain first without integration concerns It’s in operation at all stages of development, not just up-front Reminded of a problem domain related to managing meetings and attendees - focused so hard on the DB tables that the program logic was a dog’s breakfast.
  • 12. from Wikmedia Commons Wednesday, 11 September 13 We can use the model to calculate useful information, such as how long it takes for a ball to roll down a hill The model only includes significant complexity - ignores the rest Formula 1 makes use of CFD because they need it at the bleeding edge
  • 13. Remember: you’re trying to solve a business problem Wednesday, 11 September 13 You need to understand the problem domain The model needs to reflect that understanding Gradle is a great example of a rich, evolving, and useful domain model
  • 14. The Life Preserver Domain REST Persistence Messaging Events Courtesy of Simplicity Itself Wednesday, 11 September 13 Note how persistence is treated as an integration point Opens up novel approaches Could use mybatis + Flyway instead of GORM for example
  • 15. An example - reporting ReportController ReportService Jasper Wednesday, 11 September 13 High volume transactional web site, optimised for write Everything was OK at this point
  • 16. An example - reporting ReportController ReportService Jasper + HTML reports with paging Breakage! Wednesday, 11 September 13 The logic for building reports was complex Who is responsible for the paging? The HTML generation? Where is the state kept? The service? A domain class?
  • 17. An example - reporting PublisherReport HTTP Request Summary Table 1 Table 2 ... Table N It’s a command object! Wednesday, 11 September 13 Let’s try again The logic for building the report and pagination is in the PublisherReport class
  • 18. An example - reporting class ReportController { def print(PublisherReport report) { JasperRenderer.render report } def json(PublisherReport report) { render report as JSON } ... } Wednesday, 11 September 13 The controller is now very thin The report can support parameters for sub-reports etc. The domain model is embodied in the command object
  • 20. C Q R S ommand uery esponsibility egregation Wednesday, 11 September 13 The writes use a different model from the reads Will be coming back to this later
  • 21. What is my domain? Domain Model HTTP Database ? ? Wednesday, 11 September 13 Always ask yourself this question throughout life of project And is it closer to the user’s perspective or the persistence model? Or neither? Former argues for a model based on command objects, the latter based on domain classes.
  • 22. Post content Wednesday, 11 September 13 The command model is very simple: author + post content + date
  • 23. Wednesday, 11 September 13 Query model much more complex Multiple timelines Conversation threads Retweets
  • 24. Wednesday, 11 September 13 So working from your domain first is a good thing And remember that different contexts have potentially different views of the model, i.e. the user/client, persistence, other system components DDD doesn’t preclude the CRUD/service-based architecture So what are the driving forces behind architecture beyond the model?
  • 25. Rich clients Wednesday, 11 September 13 We’re not talking Warren Buffet here Things like GMail
  • 26. Once upon a time... Wednesday, 11 September 13
  • 27. Flash Wednesday, 11 September 13 Pretty (but often useless - or just pretty useless)
  • 28. Java Wednesday, 11 September 13 Remember applets? Liked the approach (particularly WebStart) but not often used. The browser was a delivery mechanism, not a platform
  • 29. It’s all about the Javascript! AngularJS Knockout.js Backbone.js Underscore.js jQuery.js Moustache Wednesday, 11 September 13 The browser is now a platform for rich applications But how do these impact the Grails app? The whole process of building a page on each request goes out the window
  • 30. Google I/O 2012 Android activations to date 400 million Apple WWDC 2012 iOS devices sold to date 365 million Wednesday, 11 September 13 Let’s not forget Firefox OS Lots of people potentially hitting a site at any one time! Typical Grails architecture may struggle to handle the load (OpenSessionInViewInterceptor, transactions, GSPs, thread-per-request)
  • 31. An aside If the whole Java client thing had worked out, would you use it for every web application you wrote? Would you use it for Wikipedia? Wednesday, 11 September 13 Before jumping onto the whole “single-page app” bandwagon, work out whether it’s appropriate for your app
  • 32. Shared templates HandlebarsViewResolver or <hbt:render template="..."/> GSP Wednesday, 11 September 13 Not much to talk about on client architecture, but template reuse is something to think about View resolver only makes sense if client-side templates are complete views hbt is a fictitious tag namespace representing a plugin based on Handlebars for Java
  • 33. AJAX + JSON endpoints enabler for async Wednesday, 11 September 13 Rich UIs don’t talk HTML - use JSON endpoints (aka “REST”) Asset delivery via Resources or asset-pipeline plugins More scope for asynchronicity, since no wait for full page update Grails 2.3 introduces some nice features for REST
  • 34. What’s the need for SiteMesh & GSP then? Wednesday, 11 September 13 Difficult to impossible to remove these currently Grails 3 will finally extricate them, allowing you to remove them from your project
  • 35. Aside 2 Don’t be afraid to use Ruby/Node.js tooling Grunt Bower Yeoman Compass/SASS Wednesday, 11 September 13 If you go for a heavy Javascript UI, consider Ruby/Node.js tooling Generally richer than Java-based tooling
  • 36. Async for scalability Wednesday, 11 September 13 To solve the problem of dealing with large number of concurrent requests Without adding lots more servers
  • 37. Grails Promise API import static grails.async.Promises.* class ReportController { def print(PublisherReport report) { task { // Expensive report creation here } } ... } Wednesday, 11 September 13 We can now return Promise instances from actions The expensive task no longer blocks the request thread, but...
  • 38. Controller Request Thread Pool Worker Thread Pool HTTP Request Offload Task Return thread Wednesday, 11 September 13 The request threads are now free, but burden is on worker thread pool If all worker tasks are synchronous, have we gained scalability? In cases where just a few URLs are blocking for long(ish) periods of time, yes (kind of) But otherwise, now bottleneck is on worker thread pool
  • 39. Make efficient use of server resources Wednesday, 11 September 13 Async all the way through - Grails Promises, GPars, messaging Remember that some things are inherently synchronous (think Fibonacci)
  • 40. Grails app ReportController TagService PostService Remote access Wednesday, 11 September 13 NetFlix style model: coarse-grained, self-contained services/apps accessed from other apps Usually via REST
  • 41. Async controllers import static grails.async.Promises.* class ReportController { def tagService def postService def home() { tasks tags: tagService.tagsWithCount() trends: tagService.trendingTags() timeline: postService.timeline( params.userId) } ... } Wednesday, 11 September 13 tagService and postService are both async The model values are evaluated in parallel This is a PromiseMap - view rendered only when all map values evaluated
  • 42. Async controllers import static grails.async.Promises.* class TagService { def remoteTagService def tagsWithCount() { task { remoteTagService.tagsWithCount() } } ... } Wednesday, 11 September 13 You can also use @DelegateAsync to create async version of synchronous service Currently not Grails’ sweet spot due to the solution’s lightweight nature... ...perhaps makes sense with Grails 3?
  • 43. Rich domain model + Promises API/GPars? Wednesday, 11 September 13 Fully async backend A good domain model makes it easy to identify parallelisable work No simple solutions though! Concurrency is still a tricky problem.
  • 44. GPars supports • Dataflow • Communicating Sequential Processes (CSP) • Actor model Wednesday, 11 September 13
  • 45. Messaging Wednesday, 11 September 13 A common solution to concurrency and scale
  • 47. MyObject TheirObject Router Router message response response message Headers Body Wednesday, 11 September 13 Decoupling via messages Encourages separation of concerns & responsibilities
  • 48. MyObject OtherObject Router Router message message response response Cloud Wednesday, 11 September 13 Easy to change and move objects Scales well (think Actor model of concurrency)
  • 49. Internal External JMS RabbitMQ Events Spring Integration Apache Camel Wednesday, 11 September 13 Internal and external can be integrated Events is a special case of messaging (which I look at next)
  • 50. Spring Integration MyController MyService message DB Persister SplitterJMS Twitter A channel (pipe) Message endpoint Wednesday, 11 September 13 Based on Enterprise Integration Patterns (filters & pipes) Many options for routing and transforming messages Logging adapters and wire tapping for debug
  • 51. Spring Integration Groovy DSL def builder = new IntegrationBuilder() def ic = builder.doWithSpringIntegration { messageFlow("flow") { filter { it == "World" } transform(inputChannel: "transformerChannel") { "Hello " + it } handle { println "**** $it ****" } } } ic.send "flow.inputChannel", "World" ic.send "transformerChannel", "Earth" Wednesday, 11 September 13
  • 52. Debugging Code comprehension Performance (kind of) Wednesday, 11 September 13
  • 53. Events Wednesday, 11 September 13 Special case of messaging
  • 54. Event bus - ApplicationContext ApplicationContext PluginService publish PluginUpdateService YourListener GORM Wednesday, 11 September 13
  • 55. Event bus - ApplicationContext class PluginService { def publish(PluginDetails info) { ... publishEvent(new PluginUpdateEvent(...)) } } class PluginUpdateService implements ApplicationListener<PluginUpdateEvent> { def onApplicationEvent(PluginUpdateEvent e) { ... } } Wednesday, 11 September 13 with spring-events plugin
  • 56. Immutable “mesages” @groovy.transform.Immutable class PluginUpdateEvent { String name String version String group ... } Wednesday, 11 September 13 Event listeners on separate threads (from thread pool)
  • 57. Event bus - (grails-)events Event bus (Reactor) PluginService publish PluginUpdateService YourListener Wednesday, 11 September 13
  • 58. Event bus - (grails-)events Event bus (Reactor) Browser RabbitMQ (pending) events-push plugin Wednesday, 11 September 13
  • 59. Event bus - (grails-)events class PluginService { def publish(PluginDetails info) { ... event "pluginUpdate", info } } class PluginUpdateService { @Selector def pluginUpdate(PluginDetails info) { ... } } Wednesday, 11 September 13 with spring-events plugin
  • 60. AppEvents.groovy includes = ["push"] doWithReactor = { reactor("grailsReactor") { ext "browser", ["pluginUpdate"] } } Wednesday, 11 September 13 In grails-app/conf Can control which events are propagated to the browser The “push” include sets up a
  • 61. Include grailsEvents.js window.grailsEvents = new grails.Events(baseUrl) grailsEvents.on("pluginUpdate", function(data) { // do something }); Wednesday, 11 September 13
  • 62. A CQRS architecture Updates Views Concurrency via event bus Store changes Separate data stores for queries Wednesday, 11 September 13 Why? Updates and querying often have different data requirements. For example, Lanyrd use Redis structured data support All read databases can be rebuilt from master events DB CQRS designed for scale
  • 63. Plugin Architectures App Feature plugin 1 Feature plugin 2 Feature plugin 3 Events/SI/Message broker Wednesday, 11 September 13 So why use messages to interact between the plugins?
  • 64. Plugin Architectures App Feature plugin 1 Feature plugin 2 Feature plugin 3 Events/SI/Message broker App 2 Wednesday, 11 September 13 Easy to separate out into apps deployed independently
  • 65. Ultimately, think about what you need... Wednesday, 11 September 13
  • 66. ...don’t just go the “standard” route automatically Wednesday, 11 September 13
  • 67. Thank you Wednesday, 11 September 13