Grails scaffolding

Grails est un framework web Groovy qui se vante de haute-productivité. Mais qu’est-ce qui lui permet de se prétendre plus productif qu’un autre framework ? Un de ses meilleurs atouts s’appelle le scaffolding. Le scaffolding, c’est le générateur de code de grails qui permet de créer une application entière en cinq minutes à partir des objets métier ! Dit comme ça, ça fait rêver ! Oui, mais j’entends déjà les détracteurs des générateurs de code qui hurlent à l’illusion du gain de productivité… Et bien peut-être pas, pour une fois !

Qu’est-ce que le scaffolding ?

Le scaffolding (« l’échafaudage » pour les puristes francologues), c’est l’effet « magique » de Grails, ou « comment générer toute une application CRUD à partir de quelques classes métier ». Voyons de plus près comment le scaffolding fonctionne.
…LE scaffolding !? LES scaffolding plutôt. Car Grails propose deux approches différentes pour générer les écrans à partir des classes métier : statique ou dynamique.

Regardons d’abord le scaffold statique.

Scaffolding statique

Commençons par créer 2 classes métier (domain en grails) :

grails create-app bookstore
grails create-domain-class Book

Ajoutons les attributs suivants à la classe créée :

class Book {

    String title
    String author

    static constraints = {}
}

Puis générons les écrans CRUD avec la commande suivante :

grails generate-all Book

Cela génère le controller (BookController) et les pages dans views/book : create.gsp, edit.gsp, list.gsp, show.gsp.

Admirez le résultat en lançant l’application :

grails run-app

Ce scaffolding statique est finalement juste un générateur de code comme on peut en trouver dans beaucoup de frameworks. Et comme tout générateur de code, son intérêt est assez limité puisqu’à la moindre évolution de la classe Book (ajout d’un attribut par exemple), il faudra tout regénérer.

C’est là que vient le scaffold dynamique ! Recommençons depuis la création de la classe Book.

Scaffolding dynamique

Après l’object domain, créons le controller. Manuellement (dans grails-app/controllers) ou avec la commande :

grails create-controller Book

Ouvrons la classe générée BookController et ajoutons l’attribut scaffold :

class BookController {

    def scaffold = true
}

Lancez l’application et admirez de nouveau : le résultat est identique. Mais quel est l’intérêt alors ? L’intérêt n’est pas visible mais il est pourtant de taille pour nous les développeurs : la maintenance ! Nous avons ici une solution beaucoup plus souple qui va s’adapter aux modifications de l’objet métier.

Reprenons la classe Book et ajoutons un attribut description :

class Book {

    String title
    String author
    String description

    static constraints = {}
}

Relancez l’application et vous pouvez voir le nouveau champ.

Personnalisation du scaffolding

Comme vous l’avez peut-être remarqué, les champs du formulaire de création ne sont pas forcément dans l’ordre le plus intuitif (author avant title) et le champ description est un peu court.
Heureusement, le scaffolding est suffisamment intelligent et se base sur les constraints de l’objet métier.

Pour changer l’ordre d’affichage des champs, il suffit de déclarer les contraintes de ces champs dans l’ordre désiré :

class Book {

    String title
    String author
    String description

    static constraints = {
        title()
        author()
        description()
    }
}

Mais ce n’est pas tout, ajoutons quelques attributs pour illustrer les capacités du scaffolding :

class Book {

    String title
    String author
    Date publicationDate
    String category
    String description
    boolean available

    static constraints = {
    	title(blank:false)
    	author()
    	publicationDate()
    	category(inList:['Groovy', 'Java', '.Net'])
    	description(widget:'textarea')
    	available()
    }
}

Regardons les contraintes :

  • « blank:false » rend le champ obligatoire
  • « inList » génère un élément <select> avec les valeurs spécifiées
  • « widget:’textarea' » génère un élément HTML <textarea>

Static vs dynamic

Le scaffold statique fonctionne comme n’importe quel générateur de code. Vous concevez votre objet métier puis vous générez le controller et les vues. Mais à chaque modification de l’objet renommer un attribut par exemple vous devrez mettre à jour les méthodes du controller et les 4 pages gsp. Beaucoup de travail pour une si petite modification.
Or les objets métier sont modifiés très souvent durant la vie d’un projet (surtout dans un développement agile).

Le scaffold dynamique permet d’éviter cette perte de temps puisque les modifications de l’objet métier sont automatiquement répercutées sur les vues au démarrage de l’application. Le gain de temps est donc énorme !

Conclusion

La différence entre le scaffolding statique et le scaffolding dynamique se résume au moment du cycle de développement où le code est généré. Le code statique est généré par le développeur alors que le code dynamique est généré au runtime. Mais cette petite différence a un énorme impact en terme de maintenance : le scaffold dynamique permet de se concentrer sur le code métier, alors que le scaffold statique oblige à maintenir inutilement les vues et le controller générés.

Grails possède donc avec le scaffolding dynamique un atout précieux qui permet réellement d’augmenter la productivité. Cette fonctionnalité risque à l’avenir de se retrouver dans un grand nombre de frameworks tant elle est bénéfique.

En étant honnête, les écrans CRUD ne pourront que rarement être exposés tels quels au grand public. Mais dans toutes les applications de gestion, la plus grosse partie est la partie immergée, le back-office. Et là, il est tout à fait envisageable d’exposer ces écrans en interne dans l’entreprise.

On peut regretter toutefois que la liste du CRUD ne propose pas de possibilités de recherche ou de filtre, car une liste même paginée devient vite inutilisable dès qu’on dépasse 3 pages. On peut aussi reprocher quelques lacunes niveau ergonomie mais on peut espérer que le scaffold va s’améliorer au fur et à mesure des versions de Grails.

Sinon, Grails offre la possibilité de modifier complètement les templates utilisés pour générer le code, mais ça ce sera pour la prochaine fois !

6 commentaires

  • Comment se passe la personnalisation des pages ?
    Si je modifie mon code, je ne risque pas d’écraser mes modifications lors de la génération ?
    Ou alors si je comprends bien la petite phrases de fin, le mode opératoire est différent, je passe par une template ?

  • @Guillaume : Très bon article qui résume la technique de scaffolding en Grails.

    @Nicolas: lors de la génération du code (contrôleurs et vues), Grails vérifie s’il y a déjà des fichiers générés, et il demande une confirmation avant d’écraser les modifications.
    C’est bien l’un des inconvénients de ce type de framework de génération de code.

  • Bonjour.

    Je trouve cet article très intéressant, mais je m’interroge.

    Vous citez « la maintenance » comme un des avantages du scaffolding dynamique, puisque c’est une solution qui s’adapte aux modifications de l’objet métier.

    Le scaffolding dynamique est-il donc puissant au point de permettre la mise en place d’une interface d’admin avec des cas d’utilisation souvent très spécifiques ? Ou bien ne peut t’on réaliser que de simples CRUD, qui n’ont un intérêt que pour les démos et les prototypes ?

    Dans l’article suivant : http://blog.excilys.com/2009/12/21/grails-episode-3-branchement-des-controleursvuesservices/ , l’auteur estime que « les commandes de génération ne sont à utiliser qu’une seule fois au début du projet et sont à bannir par la suite ».

    Ces différents points de vues m’intéressent. Quelqu’un a t’il des retours d’expérience sur le sujet ? Et qu’en est-il de la maintenance ?

  • Bonjour,

    @Nicolas : effectivement pour personnaliser le code généré, il faut d’abord copier les templates dans le projet à l’aide de la commande « grails install-templates ». On peut ainsi modifier les gsp et le template du controller. Voir http://www.grails.org/Artifact+and+Scaffolding+Templates mais c’est assez léger. J’espère en parler plus en détail prochainement dans un autre article.

    @Piwai : excylis et moi sommes d’accord sur un point. « les commandes de génération » font référence au scaffolding statique, qui génère le code des gsp et du controller. Excylis parle du cas où il modifie manuellement le code généré, solution non viable puisque qu’à la prochaine exécution de la commande de génération, les modifications seront écrasées. On est donc d’accord, le scaffolding statique n’est (presque) jamais une bonne solution.
    Le scaffolding dynamique est bien plus utile. Est-il puissant au point de mettre en place des cas d’utilisation très spécifiques (au projet ? à un objet métier ?) ? Je pense que non, ce n’est pas raisonnable de vouloir faire du « très spécifique » avec de la génération de code. Par contre le scaffolding dynamique permet d’avoir un CRUD sur tous les objets métier de l’application via une interface personnalisée au projet. Or là où je ne suis pas d’accord avec toi, c’est sur l’utilité du CRUD. Le CRUD est un besoin récurrent de tous les projets. Ne serait-ce que les écrans de création, ils sont indispensables au métier pour remplir la base. Et après le métier a besoin de consulter les données créées, les corriger, les modifier, les supprimer. Bref les données ne sont jamais figées et le CRUD permet au métier de les manipuler directement.
    Nous avons mis ce CRUD d’admin en place sur un projet (qui tourne en production), et la maintenance se résume à la modification des objets domain, sans impact pour l’interface d’admin.

    Cependant tu as raison, il y a toujours des besoins spécifiques. Par exemple nous voulions changer complètement l’affichage de la liste pour un objet domain particulier mais nous voulions garder l’édition/création/modification proposée par grails.
    Nous avons donc surchargé la méthode list du controller (en gardant l’attribut scaffold = true) afin de ne ramener que certains éléments (par défaut tous les éléments de la table sont affichés). Ensuite nous avons généré la list.gsp (pour ne pas partir de zéro, « grails generate-views » puis suppression des 3 gsp qui ne nous intéressent pas), puis nous avons personnalisé son affichage (précision pour Nicolas, cette page list.gsp modifiée ne sera pas écrasée par le scaffolding dynamique. Au démarrage de l’application Grails ne génère que les méthodes de controller et vues manquantes).
    La liste répond désormais au besoin spécifique tout en gardant l’avantage du scaffolding dynamique pour les autres vues de cet objet. C’est cette souplesse qui est très appréciable avec Grails.
    Par contre la maintenance de cette liste est évidemment manuelle et donc alourdit un peu l’application. Mais ce genre de besoins spécifiques ne concernent que quelques objets (sur notre projet en tous cas), la grande majorité des écrans d’admin sont complètement générés dynamiquement, ce qui nous fait gagner un temps précieux !

  • @Guillaume : merci pour cette réponse détaillée, cela éclairci nettement mon point de vue.

  • Bonjour,
    k’aimerai savoir comment on scaffolde un template sous grails. faire de tel sorte que le meme template soit pris en compte na chaque génération de page.
    merci

Laisser un commentaire