SlideShare uma empresa Scribd logo
1 de 53
Grails EE
Ivo Houbrechts
     Ixor
About myself


    ▸   Ivo Houbrechts
    ▸   Belgium
    ▸   Grails user and plugin developer
    ▸   ivo.houbrechts@ixor.be




2
About Ixor


    ▸   Since 2002
    ▸   40 experienced ICT professionals
    ▸   Software development for the JVM
    ▸   Consultancy and product development
    ▸   Loyal customers in Finance, Telecom and
        Government




3
Agenda


    ▸   Grails as part of Java EE
    ▸   Enterprise telco app
    ▸   Development environment
    ▸   Development productivity
    ▸   Plugins
    ▸   Conclusions




4
Agenda



    ▸   Enterprise telco app
    ▸   Development environment
    ▸   Development productivity
    ▸   Plugins
    ▸   Conclusions




4
Enterprise application




5
The application


    ▸ Order intake and customer care
      – used by call center and dealers
      – 1000 users
    ▸ 75 tailored screens
      – complex compositions




6
Deployment


    ▸ ESB backend
      – SOAP web services
      – no direct database access
      – domain defined in XSD’s
      – Spring / JAXB (code generation)
    ▸ Weblogic 10 cluster




7
Development environment




8
To Grails or not to Grails


    ▸ Spring MVC + Freemarker
       – no components
       – (almost) no IDE support
    ▸ project behind schedule
      ➭ speed up with Grails




9
To Grails or not to Grails


    ▸ Spring MVC + Freemarker
       – no components
       – (almost) no IDE support




                                   ?
    ▸ project behind schedule
      ➭ speed up with Grails




9
Build


     ▸ Multi module Maven project
       –Command line Grails
        • Mix Ivy and maven dependency resolution
        • CI agents need both Maven and Grails
        • Improved maven support in Grails 2.1

      –9 modules
        • JAXB / WS
        • AST
        • Grails inline plugins
        • Grails war, ear, config resources




10
Development team



     ▸ 2 scrum teams, 14 developers
     ▸ Groovy / Grails experience is rare
     ▸ Learning curve
       – 2 weeks self study
       – dynamic language
       – Intellij IDEA
     ▸ Vast majority enthusiastic




11
Development productivity




12
Modularization


     ▸ (inline) plugin system
     ▸ plugins are standalone apps
       – views, web.xml, bootstrap, spring beans, url mappings...
     ▸ reuse across applications
     ▸ plugin compilation time
       – Grails 2 binary plugins




13
AST transformations




     ▸ Compiler plugin
     ▸ Rather complex
     ▸ Only for framework developers?




14
AST transformations




     ▸ Compiler plugin
     ▸ Rather complex




14
AST example 1



BillingType getBillingType() {
        return data.customer.customerBillingInfo.customerBillType
}

void setBillingType(BillingType billingType) {
    data.customer.customerBillingInfo.customerBillType =
                                                 billingType.data
}




15
AST example 1




                BillingType getBillingType() {
                        return data.customer.customerBillingInfo.customerBillType
                }

                void setBillingType(BillingType billingType) {
                    data.customer.customerBillingInfo.customerBillType =
                                                                 billingType.data
                }




@PropertyDelegate('customer.customerBillingInfo.customerBillType')
BillingType billingType




15
AST example 2



private productOffering

ProductOffering getProductOffering() {
    if (!productOffering) {
        productOffering = ProductCatalog.get(ProductOffering,
                                  data.typeInfo.productOfferingId)
    }
    return productOffering
}




16
AST example 2




                private productOffering

                ProductOffering getProductOffering() {
                    if (!productOffering) {
                        productOffering = ProductCatalog.get(ProductOffering,
                                                  data.typeInfo.productOfferingId)
                    }
                    return productOffering
                }




@ProductCatalog('typeInfo.productOfferingId')
ProductOffering productOffering




16
AST example 3

List<ContactInfo> getContactInfoList() {
    List<ContactInfo> result = []
    for (contactInfo in data.customer.contactInfoList.contactInfo) {
        result << contactInfo.createNewWrapperInstance()
    }
    return result
}

void clearContactInfoList() {
    data.customer.contactInfoList.contactInfo.clear()
}

void addToContactInfoList(ContactInfo contactInfo) {
    data.customer.contactInfoList.contactInfo << contactInfo.data
}

void addAllToContactInfoList(List<ContactInfo> contactInfoList) {
    for (contactInfo in contactInfoList) {
        addToContactInfoList(contactInfo)
    }
}

void removeFromContactInfoList(ContactInfo contactInfo) {
    data.customer.contactInfoList.contactInfo.remove(contactInfo.data)
}



17
AST example 3


                List<ContactInfo> getContactInfoList() {
                    List<ContactInfo> result = []
                    for (contactInfo in data.customer.contactInfoList.contactInfo) {
                        result << contactInfo.createNewWrapperInstance()
                    }
                    return result
                }

                void clearContactInfoList() {
                    data.customer.contactInfoList.contactInfo.clear()
                }

                void addToContactInfoList(ContactInfo contactInfo) {
                    data.customer.contactInfoList.contactInfo << contactInfo.data
                }

                void addAllToContactInfoList(List<ContactInfo> contactInfoList) {
                    for (contactInfo in contactInfoList) {
                        addToContactInfoList(contactInfo)
                    }
                }

                void removeFromContactInfoList(ContactInfo contactInfo) {
                    data.customer.contactInfoList.contactInfo.remove(contactInfo.data)
                }




@PropertyDelegate('customer.contactInfoList.contactInfo')
List<ContactInfo> contactInfoList




17
AST summary


     ▸ AST transformation code: 800 lines
       – Java
       – Groovy in separate module
     ▸ But:
       –   200+ domain classes
       –   1000+ usages
       –   ~10K lines omitted
       –   improved readability!




18
UI components

     ▸ Version 1
       – 12 screens
       – html tags in GSPs
       – Example: first name edit field




19
UI components 2.0


     ▸ Version 2




20
UI components 2.0


     ▸ Version 2




20
UI components


     ▸ Html in GSPs becomes problematic
        – huge GSPs
        – virtual impossible to change look and feel
        – inconsistent development
       ➭ custom tags / components with documented
       API




21
UI components




22
UI components




22
UI components

     ▸ Reusable Grails plugin with kitchen sink
     ▸ 65 components
       –   Form row
       –   Input
       –   Layout (section, box, buttons, links ...)
       –   Ajax
       –   Behavior (autocomplete, menu, toggle ...)




23
UI components


     ▸ Grails tag
          – documented component API, code completion
          – ideal for logic
          – not suited for markup:

def box   = { attrs, body ->
    out   << “<div class=”box $clazz>”<div class=”boxHeader”>”
    out   << attrs.header << “</div><div class=”boxBody”>”
    out   << body()
    out   << “<div>”
}




24
UI components


     ▸ tmpl namespace
       – markup in GSP
       – simple to use

       – no documented API, no code completion, etc.
     ▸ render template from tag
       – markup in GSP
       – documented API, code completion, etc.
       – maintenance hell




25
UI components

     ▸ GSP taglib plugin
       –   simple to use
       –   documented API, code completion, etc.
       –   tags in taglib directory
       –   generated xxxTagLib.groovy




26
UI components

     ▸ GSP taglib plugin
       –   simple to use
       –   documented API, code completion, etc.
       –   tags in taglib directory
       –   generated xxxTagLib.groovy




26
Plugins




27
Rich domain validation


     ▸ Validation for non-Grails domain classes
       – web services
       – deep nested objects
       – limited build-in support
     ▸ Extended validation
       –   cascaded validation
       –   partial validation
       –   constraint groups
       –   instance validation




28
Rich domain validation

class OrderItem {
... ▸ Validation for non-Grails domain classes
  static web services = {
        – constraints
        – deep nested objects
    //instance constraint
        – limited build-in support
    forbiddenAtLineLevel(validator: {
    ...
    }) Extended validation
     ▸
        – cascaded validation
    //constraint group
        – partial validation
    characteristicsOnly {
        – constraint groups
         characteristics(cascade: true)
          instance validation
        –childOrderItems(cascade:
                                   [excludes:'forbiddenAtLineLevel']])
    }
  }
}

orderItem.validate(groups: [“characteristicsOnly”],
                 includes: [“*.delivery”],
 28              excludes: [...])
29
order.validate(groups: [“deliveryInformation”])




29
Rich domain DI



     ▸ DI for non-Grails domain classes
       – @Inject, @Resource
       – auto wiring at object initialization and de-serialization
       – move logic from controllers to domain classes
     ▸ see http://livesnippets.cloudfoundry.com

@RichDomain
class Customer {
   @Inject
   transient CustomerWebService customerWebService
  ...
}




30
Geb


     ▸ In-browser functional tests
     ▸ Maintainable tests
       – Pages / Modules
     ▸ Test javascript and (partial) css
       – Ajax timing issues




31
Webflow


     ▸ Indispensable for
       – wizards
       – page flows
     ▸ see http://livesnippets.cloudfoundry.com




32
Resources



     ▸ Organize javascript and css
       – jawr
       – less css
     ▸ Grails 2.0 : resources plugin




33
Conclusions




34
Developer experience



     ▸ Frustrations
       –   Build
       –   debugger
       –   Runtime vs compile time errors
       –   Grails upgrades
     ▸ Satisfaction
       – Groovy power
       – Convention over configuration
       – Fun
     ▸ Generally enthusiastic



35
Developer experience



     ▸ Frustrations
       –   Build
       –   debugger
       –   Runtime vs compile time errors
       –   Grails upgrades
     ▸ Satisfaction
       – Groovy power
       – Convention over configuration
       – Fun
     ▸ Generally enthusiastic



35
Development cost


     ▸ Fast kickoff with Grails
       – GORM
       – Scaffolding
     ▸ Short term development cost
       – Determined by domain complexity
       – Technology is minor factor
     ▸ Long term benefits
       – Code size
       – Code readability




36
Development cost


     ▸ Fast kickoff with Grails
       – GORM
       – Scaffolding
     ▸ Short term development cost
       – Determined by domain complexity
       – Technology is minor factor
     ▸ Long term benefits
       – Code size
       – Code readability




36
Development cost


     ▸ Fast kickoff with Grails
       – GORM
       – Scaffolding
     ▸ Short term development cost
       – Determined by domain complexity
       – Technology is minor factor
     ▸ Long term benefits
       – Code size
       – Code readability




36
Development cost


     ▸ Fast kickoff with Grails
       – GORM
       – Scaffolding
     ▸ Short term development cost
       – Determined by domain complexity
       – Technology is minor factor
     ▸ Long term benefits
       – Code size
       – Code readability




36
?
38

Mais conteúdo relacionado

Mais procurados

Guice tutorial
Guice tutorialGuice tutorial
Guice tutorialAnh Quân
 
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術Seitaro Yuuki
 
Meet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIMeet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIICS
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentICS
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4ICS
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleSkills Matter
 
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIBest Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIICS
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeedYonatan Levin
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4ICS
 
Universal Declarative Services
Universal Declarative ServicesUniversal Declarative Services
Universal Declarative Servicesschemouil
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentSchalk Cronjé
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemGuardSquare
 
2005 Oopsla Classboxj
2005 Oopsla Classboxj2005 Oopsla Classboxj
2005 Oopsla Classboxjbergel
 
Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3ICS
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsBartosz Kosarzycki
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
C++ interoperability with other languages
C++ interoperability with other languagesC++ interoperability with other languages
C++ interoperability with other languagesAlberto Bignotti
 

Mais procurados (20)

Guice tutorial
Guice tutorialGuice tutorial
Guice tutorial
 
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術
ScalaMatsuri 2016 ドワンゴアカウントシステムを支えるScala技術
 
Meet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIMeet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UI
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI development
 
Concurrencyproblem
ConcurrencyproblemConcurrencyproblem
Concurrencyproblem
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIBest Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part III
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeed
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Universal Declarative Services
Universal Declarative ServicesUniversal Declarative Services
Universal Declarative Services
 
Using the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM DevelopmentUsing the Groovy Ecosystem for Rapid JVM Development
Using the Groovy Ecosystem for Rapid JVM Development
 
Eric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build systemEric Lafortune - The Jack and Jill build system
Eric Lafortune - The Jack and Jill build system
 
2005 Oopsla Classboxj
2005 Oopsla Classboxj2005 Oopsla Classboxj
2005 Oopsla Classboxj
 
Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
C++ interoperability with other languages
C++ interoperability with other languagesC++ interoperability with other languages
C++ interoperability with other languages
 

Semelhante a Grails EE

Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...InfluxData
 
Android Jetpack - Google IO Extended Singapore 2018
Android Jetpack - Google IO Extended Singapore 2018Android Jetpack - Google IO Extended Singapore 2018
Android Jetpack - Google IO Extended Singapore 2018Hassan Abid
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Max Pronko
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsAdégòkè Obasá
 
Relevance trilogy may dream be with you! (dec17)
Relevance trilogy  may dream be with you! (dec17)Relevance trilogy  may dream be with you! (dec17)
Relevance trilogy may dream be with you! (dec17)Woonsan Ko
 
Google Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleGoogle Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleMathias Seguy
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJames Casey
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksMike Hugo
 
Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03Kevin Juma
 
Webinar: ArangoDB 3.8 Preview - Analytics at Scale
Webinar: ArangoDB 3.8 Preview - Analytics at Scale Webinar: ArangoDB 3.8 Preview - Analytics at Scale
Webinar: ArangoDB 3.8 Preview - Analytics at Scale ArangoDB Database
 
Sprint 49 review
Sprint 49 reviewSprint 49 review
Sprint 49 reviewManageIQ
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Paulo Gandra de Sousa
 
Complex realtime event analytics using BigQuery @Crunch Warmup
Complex realtime event analytics using BigQuery @Crunch WarmupComplex realtime event analytics using BigQuery @Crunch Warmup
Complex realtime event analytics using BigQuery @Crunch WarmupMárton Kodok
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 

Semelhante a Grails EE (20)

Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
 
Android Jetpack - Google IO Extended Singapore 2018
Android Jetpack - Google IO Extended Singapore 2018Android Jetpack - Google IO Extended Singapore 2018
Android Jetpack - Google IO Extended Singapore 2018
 
Grails66 web service
Grails66 web serviceGrails66 web service
Grails66 web service
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web Apps
 
Relevance trilogy may dream be with you! (dec17)
Relevance trilogy  may dream be with you! (dec17)Relevance trilogy  may dream be with you! (dec17)
Relevance trilogy may dream be with you! (dec17)
 
groovy & grails - lecture 9
groovy & grails - lecture 9groovy & grails - lecture 9
groovy & grails - lecture 9
 
Google Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleGoogle Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification Google
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Building Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And TricksBuilding Grails Plugins - Tips And Tricks
Building Grails Plugins - Tips And Tricks
 
Sprint 69
Sprint 69Sprint 69
Sprint 69
 
Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03Groovygrailsnetbeans 12517452668498-phpapp03
Groovygrailsnetbeans 12517452668498-phpapp03
 
Webinar: ArangoDB 3.8 Preview - Analytics at Scale
Webinar: ArangoDB 3.8 Preview - Analytics at Scale Webinar: ArangoDB 3.8 Preview - Analytics at Scale
Webinar: ArangoDB 3.8 Preview - Analytics at Scale
 
Sprint 49 review
Sprint 49 reviewSprint 49 review
Sprint 49 review
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)
 
PoEAA by Example
PoEAA by ExamplePoEAA by Example
PoEAA by Example
 
Complex realtime event analytics using BigQuery @Crunch Warmup
Complex realtime event analytics using BigQuery @Crunch WarmupComplex realtime event analytics using BigQuery @Crunch Warmup
Complex realtime event analytics using BigQuery @Crunch Warmup
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
AngularJS in large applications - AE NV
AngularJS in large applications - AE NVAngularJS in large applications - AE NV
AngularJS in large applications - AE NV
 

Mais de GR8Conf

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your TeamGR8Conf
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle GR8Conf
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with GebGR8Conf
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidGR8Conf
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the DocksGR8Conf
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsGR8Conf
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applicationsGR8Conf
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3GR8Conf
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGR8Conf
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEBGR8Conf
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCGR8Conf
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshopGR8Conf
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spockGR8Conf
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedGR8Conf
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGR8Conf
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and GroovyGR8Conf
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineGR8Conf
 

Mais de GR8Conf (20)

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your Team
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developer
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with Geb
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and Android
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the Docks
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature plugins
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applications
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloud
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEB
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPC
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshop
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem Revisited
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and Groovy
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual Machine
 

Último

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 

Último (20)

Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 

Grails EE

  • 2. About myself ▸ Ivo Houbrechts ▸ Belgium ▸ Grails user and plugin developer ▸ ivo.houbrechts@ixor.be 2
  • 3. About Ixor ▸ Since 2002 ▸ 40 experienced ICT professionals ▸ Software development for the JVM ▸ Consultancy and product development ▸ Loyal customers in Finance, Telecom and Government 3
  • 4. Agenda ▸ Grails as part of Java EE ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions 4
  • 5. Agenda ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions 4
  • 7. The application ▸ Order intake and customer care – used by call center and dealers – 1000 users ▸ 75 tailored screens – complex compositions 6
  • 8. Deployment ▸ ESB backend – SOAP web services – no direct database access – domain defined in XSD’s – Spring / JAXB (code generation) ▸ Weblogic 10 cluster 7
  • 10. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ▸ project behind schedule ➭ speed up with Grails 9
  • 11. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ? ▸ project behind schedule ➭ speed up with Grails 9
  • 12. Build ▸ Multi module Maven project –Command line Grails • Mix Ivy and maven dependency resolution • CI agents need both Maven and Grails • Improved maven support in Grails 2.1 –9 modules • JAXB / WS • AST • Grails inline plugins • Grails war, ear, config resources 10
  • 13. Development team ▸ 2 scrum teams, 14 developers ▸ Groovy / Grails experience is rare ▸ Learning curve – 2 weeks self study – dynamic language – Intellij IDEA ▸ Vast majority enthusiastic 11
  • 15. Modularization ▸ (inline) plugin system ▸ plugins are standalone apps – views, web.xml, bootstrap, spring beans, url mappings... ▸ reuse across applications ▸ plugin compilation time – Grails 2 binary plugins 13
  • 16. AST transformations ▸ Compiler plugin ▸ Rather complex ▸ Only for framework developers? 14
  • 17. AST transformations ▸ Compiler plugin ▸ Rather complex 14
  • 18. AST example 1 BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType } void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data } 15
  • 19. AST example 1 BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType } void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data } @PropertyDelegate('customer.customerBillingInfo.customerBillType') BillingType billingType 15
  • 20. AST example 2 private productOffering ProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering } 16
  • 21. AST example 2 private productOffering ProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering } @ProductCatalog('typeInfo.productOfferingId') ProductOffering productOffering 16
  • 22. AST example 3 List<ContactInfo> getContactInfoList() { List<ContactInfo> result = [] for (contactInfo in data.customer.contactInfoList.contactInfo) { result << contactInfo.createNewWrapperInstance() } return result } void clearContactInfoList() { data.customer.contactInfoList.contactInfo.clear() } void addToContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo << contactInfo.data } void addAllToContactInfoList(List<ContactInfo> contactInfoList) { for (contactInfo in contactInfoList) { addToContactInfoList(contactInfo) } } void removeFromContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo.remove(contactInfo.data) } 17
  • 23. AST example 3 List<ContactInfo> getContactInfoList() { List<ContactInfo> result = [] for (contactInfo in data.customer.contactInfoList.contactInfo) { result << contactInfo.createNewWrapperInstance() } return result } void clearContactInfoList() { data.customer.contactInfoList.contactInfo.clear() } void addToContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo << contactInfo.data } void addAllToContactInfoList(List<ContactInfo> contactInfoList) { for (contactInfo in contactInfoList) { addToContactInfoList(contactInfo) } } void removeFromContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo.remove(contactInfo.data) } @PropertyDelegate('customer.contactInfoList.contactInfo') List<ContactInfo> contactInfoList 17
  • 24. AST summary ▸ AST transformation code: 800 lines – Java – Groovy in separate module ▸ But: – 200+ domain classes – 1000+ usages – ~10K lines omitted – improved readability! 18
  • 25. UI components ▸ Version 1 – 12 screens – html tags in GSPs – Example: first name edit field 19
  • 26. UI components 2.0 ▸ Version 2 20
  • 27. UI components 2.0 ▸ Version 2 20
  • 28. UI components ▸ Html in GSPs becomes problematic – huge GSPs – virtual impossible to change look and feel – inconsistent development ➭ custom tags / components with documented API 21
  • 31. UI components ▸ Reusable Grails plugin with kitchen sink ▸ 65 components – Form row – Input – Layout (section, box, buttons, links ...) – Ajax – Behavior (autocomplete, menu, toggle ...) 23
  • 32. UI components ▸ Grails tag – documented component API, code completion – ideal for logic – not suited for markup: def box = { attrs, body -> out << “<div class=”box $clazz>”<div class=”boxHeader”>” out << attrs.header << “</div><div class=”boxBody”>” out << body() out << “<div>” } 24
  • 33. UI components ▸ tmpl namespace – markup in GSP – simple to use – no documented API, no code completion, etc. ▸ render template from tag – markup in GSP – documented API, code completion, etc. – maintenance hell 25
  • 34. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy 26
  • 35. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy 26
  • 37. Rich domain validation ▸ Validation for non-Grails domain classes – web services – deep nested objects – limited build-in support ▸ Extended validation – cascaded validation – partial validation – constraint groups – instance validation 28
  • 38. Rich domain validation class OrderItem { ... ▸ Validation for non-Grails domain classes static web services = { – constraints – deep nested objects //instance constraint – limited build-in support forbiddenAtLineLevel(validator: { ... }) Extended validation ▸ – cascaded validation //constraint group – partial validation characteristicsOnly { – constraint groups characteristics(cascade: true) instance validation –childOrderItems(cascade: [excludes:'forbiddenAtLineLevel']]) } } } orderItem.validate(groups: [“characteristicsOnly”], includes: [“*.delivery”], 28 excludes: [...])
  • 39. 29
  • 41. Rich domain DI ▸ DI for non-Grails domain classes – @Inject, @Resource – auto wiring at object initialization and de-serialization – move logic from controllers to domain classes ▸ see http://livesnippets.cloudfoundry.com @RichDomain class Customer { @Inject transient CustomerWebService customerWebService ... } 30
  • 42. Geb ▸ In-browser functional tests ▸ Maintainable tests – Pages / Modules ▸ Test javascript and (partial) css – Ajax timing issues 31
  • 43. Webflow ▸ Indispensable for – wizards – page flows ▸ see http://livesnippets.cloudfoundry.com 32
  • 44. Resources ▸ Organize javascript and css – jawr – less css ▸ Grails 2.0 : resources plugin 33
  • 46. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic 35
  • 47. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic 35
  • 48. Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability 36
  • 49. Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability 36
  • 50. Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability 36
  • 51. Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability 36
  • 52.
  • 53. ? 38

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n