Il y a 12 ans -
Temps de lecture 4 minutes
Grails Tips : la validation sur mesure
Le mécanisme de validation de Grails est basé sur l’API Spring Validator. Il existe dans Grails un ensemble de validateurs permettant de couvrir la plupart des besoins simples, tels que champs obligatoires, taille mini/maxi, valeurs min/max pour les nombres, etc. Cependant, il arrive souvent d’avoir besoin de validateurs sur mesure, plus adaptés au métier de l’application. Aujourd’hui nous allons voir les différentes méthodes de validation avancées des classes du domaine qui s’offrent aux utilisateurs de ce framework web magique :
- Retour sur la contrainte
validator
- Faire une contrainte réutilisable
- Le plugin Constraints
Suivez le guide…
Validation sur mesure
Il existe 16 contraintes applicables sur les attributs des classes de domaine dans une application Grails. Ces contraintes permettent de s’assurer de la validité du contenu de nos entités avant de les envoyer en base. Elles vont de la vérification de la nullité, de la taille d’une chaîne, à la correspondance à une expression régulière, et j’en passe.
Mais parfois, il est indispensable de valider nos attributs en fonction de critères plus fins, ou liés à des logiques métiers complexes. C’est alors que la 17ème contrainte livrée avec Grails peut servir : validator
.
Grâce à cette contrainte, on peut glisser une closure qui sera exécutée lors de la validation de l’entité. Voici la page de la documentation officielle qui détaille son utilisation. Pour ceux qui n’ont pas le temps d’aller lire la documentation voilà un exemple assez parlant :
class User { String login String autreChamp static constraints = { login(validator: { val, obj -> return (val.length != 0 && obj.properties['autreChamp'] != 'magicString') }) } }
Dans cet exemple, si la contrainte n’est pas respectée, alors le message d’erreur associé sera, par convention : user.login.validator.invalid
.
Ce mécanisme est très pratique et flexible, mais oblige à dupliquer du code si on souhaite utiliser la même contrainte complexe sur plusieurs classes de domaine. Poussons plus loin l’investigation.
Faire mieux, à la main
Il est possible d’écrire ses propres classes de contrainte et de les réutiliser plusieurs fois. Cet article décrit très bien la méthode à suivre. Je vais vous en tracer les grandes lignes ici, en français dans le texte.
Pour écrire un validateur réutilisable, il suffit d’étendre la classe AbstractConstraint
et d’implémenter la méthode processValidate
. En voici un exemple :
package myapp import org.codehaus.groovy.grails.validation.AbstractConstraint import org.springframework.validation.Errors class LowerCaseConstraint extends AbstractConstraint { // nom à utiliser dans les classes de domaine static NAME = 'lowerCase' String getName() { NAME } // si le validateur ne s'applique qu'à certaines classes, cette méthode permet de filtrer l'application de la contrainte boolean supports(Class type) { true } // code de la logique de validation protected void processValidate(Object target, Object value, Errors errors) { if (constraintParameter && value =~ /[A-Z]/) rejectValue target, errors, "default.invalid.${name}.message", "${name}.invalid", [constraintPropertyName, constraintOwningClass, value] as Object[] } }
La place idéale dans votre arborescence projet pour cette classe se trouve dans le répertoire src/groovy
. Une fois votre classe de contrainte terminée, il faut l’enregistrer auprès du framework pour que Grails sache où la retrouver. Pour ce faire, ajoutez cette ligne dans votre fichier grails-app/conf/Config.groovy
:
org.codehaus.groovy.grails.validation.ConstrainedProperty.registerNewConstraint myapp.LowerCaseConstraint.NAME, myapp.LowerCaseConstraint.class
Il ne reste plus qu’à vous en servir dans vos classes de domaine :
static constraints = { myProperty size: 1..20, lowerCase: true }
Le plugin existe déjà : Constraints Plugin
Mais comme souvent quand on parle de Grails : il y a un plugin pour ça ! Le plugin Constraints fourni des scripts pour générer des classes de contraintes réutilisables. En deux lignes de commandes, le tour est joué, installation et création de contrainte :
grails install-plugin constraints grails create-constraint my.package.ContrainteSurMesure
Dans la classe générée, il ne vous restera plus qu’à coder une closure de validation, comme on l’aurait fait dans la première solution. Un grand merci à Geoff Lane qui s’est donné la peine de coder ce plugin. Il est possible de configurer certains comportements de ce plugin, mais je vous laisse consulter la documentation pour découvrir dans quelle mesure.
Conclusion
L’usage du plugin Constraint est très simple et permet beaucoup de choses. N’hésitez pas à vous en servir. Je vous encourage également à exploiter au maximum la formidable extensibilité de Grails. Pourquoi ne pas coder vos validateurs dans un nouveau plugin qui s’appuiera sur le plugin Constraints ? Ainsi vous disposerez d’un paquetage de validateur sur mesure, à installer en claquant des doigts dans tout nouveau projet Grails démarrant chez vous.
What else ? :-)
Commentaire