Grails, from scratch to prod… plus vite !MAURY AurélienConsultant XebiaEmail : amaury@xebia.frTwitter : @aurelienmauryLinkedIn : http://fr.linkedin.com/in/aurelienmauryBlog : http://blog.xebia.fr
Qu'est-ce que Grails ?
Qu'est-ce que Grails ?Framework d'application web completMVC, basé sur le langage GroovyInspiré de RoR, Django, TurboGearsAdapté à la culture JavaBâti sur le rocStack éprouvée : Spring, Hibernate, Tomcat
ButsPile application web Java standardFournir un niveau d'abstraction en plusRéduire la complexitéEn outillant l'existantAugmenter la productivitéEn scriptant les tâches répétitives
ApprocheConvention over configurationPrincipe de "défaut raisonnable"Don'trepeatyourselfStructure imposée pour réduire les duplicationsPlateforme complèteMéthodologie et approche fournies
HistoireJanvier 2007Sortie de Groovy 1.0Février 2008Sortie de Grails 1.0Novembre 2008SpringSource rachète G2One
Rock StarsGuillaume Laforge(@glaforge)Leader Groovy chez SpringSourceGraeme Rocher (@graemerocher)Leader Grails chez SpringSource
Comment ça marche ?
Plateforme complète
Simplifié par GroovySyntaxe allégéeAccessible à tous les développeurs JavaClosures, Collections, Gpars, …L'essayer c'est l'adopterScripts de génération de codeFacilement extensible
Développement rapideTestCodeFixcreaterunwar
Support IDEIntellij IDEAEclipse STSNetbeans
$ grailscreate-appbookstore
Structure d'un projetbookstore|_grails-app|	|_conf		=> BootStraping, Datasources, UrlMappings|	|_controllers|	|_domain|	|_i18n		=> messages.properties internationalisés|	|_services|	|_taglib|	|_utils|	|_views		=> Groovy Server Pages|_lib			=> Dépendances Java|_scripts|_src|	|_groovy|	|_java|_test|_web-app		=> Ressources statiques: images, JS, CSS, etc
ScaffoldingGénération de CRUD à partir des entitésEconomie de tempsPopularisé par Ruby on RailsOrienté schéma base de donnéesAdopté par GrailsOrienté domaine
Scaffoldinggrailscreate-domain-classgrailscreate-controllergrailscreate-servicegrailsgenerate-all
Scaffolding
Scaffoldinggrailsgenerate-allorg.bookstore.BookBookControllerBookControllerTestgrails-app/views/book/list.gspgrails-app/views/book/show.gspgrails-app/views/book/edit.gspgrails-app/views/book/create.gsp
Scaffolding dynamiqueclass BookController {def index = {…}deflist = {…}defcreate = {…}defsave = {…}def show = {…}defedit = {…}def update = {…}defdelete = {…}}class BookController {defscaffold = true}
GORM : Mappingclass Book {	String titlestaticbelongsTo = [author: Author]statichasMany = [chapters: Chapters]staticconstraints = {titlenullable:false   }}
GORM : RequêtageBook.list(sort: 'title', order: 'asc')Book.getAll(37, 41, 43)Book.findByTitleLike("Harry P%")Book.withCriteria {eq('title', 'Harry Potter')	author {like('Rowli%')	}}
GORM : Requêtageclass Book {staticnamedQueries = {withPotterInTitle {like 'title', '%Potter%'		}	}}Book.withPotterInTitle.list()
VuesGroovy Server PagesHTML + TaglibgroovyAssemblage par SitemeshCommandé par tags GSPTaglib Grails (Prototype pour le JS)Formulaires, AJAX
Vues : exemples<g:formRemotename="myForm" 		on404="alert('not found!')" 		update="updateMe"		// onSuccess="jsFunc" 		url="[action:'show']">    Login: <input name="login" type="text"></input></g:formRemote><div id="updateMe">thisdivisupdated by the form</div>fieldRemote, remoteFunction
Vues : exemples<g:each var="book" in="${books}">     	<p>Title: ${book.title}</p>     	<p>Author: ${book.author}</p></g:each>if, else, formatDate, sortableColumn, datePicker, …
Contrôleursgrailscreate-controllerorg.bookstore.BookGénère un contrôlleur coquilleInjection de dépendancedefleNomDeMonServiceen attribut de classeHelpersrender as JSON, render as XML
Contrôleurs : exempleclass AuthorController {defspringSecurityServicedeflist = {        [	authorInstanceList: Author.list(), 	authorInstanceTotal: Author.count() ]    }}
Configuration : dépendancesgrails.project.dependency.resolution = {repositories {grailsPlugins()grailsHome()grailsCentral()mavenLocal()mavenCentral()mavenRepo "http://snapshots.repository.codehaus.org"  }dependencies {runtime 'mysql:mysql-connector-java:5.1.13'  }}
Configuration : environnementsenvironments {development {dataSource {dbCreate = "create-drop"            url = "jdbc:hsqldb:mem:devDB" }  }	test { dataSource { … } }	production { dataSource { … } }}
Environnementsgrailsrun-app		=> devgrails test run-app	=> testgrailstest-app		=> testgrailswar		=> production
ExtensibleDépôt de plugins centraliségrailsinstall-plugin …spring-security-corespring-security-uiquartzcodenarcmongodbspock…
Très extensibleapp-engine(GORM en mode JPA)groovy-plus-plusjquerysearchablegwtfeedsbirt-report…ou : grailscreate-pluginmonPlugin
ExtensiblePlugin Grails == Application Grails
Questions fréquemment posées
Intégration continue ?
Est-ce performant ?Overhead Groovy : x5-7Utilisez Groovy++ (x3-5)Productivité contre vitesse d'exécutionPas de compile check ? Pas grave.Optimisations Java"src/java" ou librairies
Et la courbe d'apprentissage ?Groovy s'apprend viteBases ~ 2 jours, Courant ~ 1 moisPièges, GORM GotchasDans l'ensemble, rien ne bloque longtempsAu delà de la carrosserieSur le Tao de Grails, la stack tu maîtriseras
La communauté est-elle active ?7 versions mineures en 1 an~ 60 Users Group sur la planète~ 800 repositoryGitHub autour de Grails~ 2500 mails par mois sur les ML
Y a-t-il du support ?
Dans quels cas utiliser Grails ?Minimum Viable Product rapideDu prototype au produit en douceurReprise d'une application existanteIHM Web rapide, intégration existant en librairieTout nouveau projet d'appli webEn toute simplicité 
Success stories
Bibliothèque
LinkothèqueGroovy homehttp://groovy.codehaus.org/Grails homehttp://www.grails.orgGrails pluginshttp://www.grails.org/plugins/An army of solipsists (thisweek in Grails)http://burtbeckwith.com/blog/
Questions ?
Merci à touset bon appétit

Grails from scratch to prod - MixIT 2010