Loupe

ASP.NET Core : Validation partagée avec React - partie 1

Dans une SPA (Single Page Application), il est souvent nécessaire de vérifier 2 fois la donnée :

  • Une fois côté client, pour pouvoir présenter une réponse visuelle à l'utilisateur si le format des données n'est pas bon,
  • Une fois côté serveur pour protéger le "vrai point d'entrée" du système ainsi que l'intégrité des données (en cas de modification malicieuse des scripts clients, mauvaise utilisation, etc.)

À ce sujet, j'ai pu échanger avec mes chers collègues Jonathan, Hamza et Benoit à ce sujet, et avec l'aide de Zack, nous avons pu mettre en place un système qui permet de ne définir qu'une seule fois les règles de validation et les répercuter à la fois côté client et serveur.

Principes du système de validation partagée

  1. Les validations sont définies côté serveur, via la librairie FluentValidation
  2. On définit un Endpoint qui va, par réflexion, récupérer tous les validateurs et va renvoyer leur description au format JSON
  3. La SPA react va récupérer les règles de validation au démarrage de l'application, puis transformer ensuite toutes ces règles en ValidationRules compréhensibles par la librairie react-hook-form
  4. Il ne reste plus qu'à lier nos données à valider aux règles de validation correspondantes, et voilà! Le tour est joué!

Il est à noter cependant que la mise en place d'un tel système a un petit coût d'entrée ainsi que de maintenance, aussi le retour sur investissement se voit plus sur des applications assez conséquentes et/ou possédant de nombreuses données à valider (ce qui, vous en conviendrez, arrive assez souvent :))

validation-partagee-aspnetcore-react-hook-form.gif
Exemple de rendu simple une fois tout le système mis en place.

Une mise en place d'exemple du système est disponible sur Github et sera référencée à maintes reprises durant ces articles.

L'explication du système en entier étant un peu longue, voyons dans ce premier article la mise en place de la partie serveur, côté aspnetcore.

Définition des règles de validation avec FluentValidation

Pour cette première partie, on reste dans de l'utilisation classique de FluentValidation (cf. doc officielle):

Une fois tout ça mis en place, il suffit de créer un nouvel endpoint utilisant un de nos Dtos pour qu'il soit validé automatiquement par FluentValidation et empêche toute saisie incomplète.

Ajout d'un endpoint retournant toutes les validations de l'application

C'est ici la partie la plus intéressante (côté serveur) de la mise en place du système !

Dans les grandes lignes, la mise en place se place comme suit :

  • Ajout d'un endpoint dans un nouveau controller appelé ValidationController
  • Cet endpoint va ensuite appeler l'interface du service de description des validators, appelé sobrement IValidationDescriptorService
  • Durant la configuration de ce service dans le fichier Startup.cs, on prendra soin de lui passer l'Assembly contenant les validators pour permettre de les récupérer par réflexion.
  • Toute la logique de transformation des validateurs de FluentValidation en Dtos va se situer dans le ValidationDescriptorService. Il se charge de retourner un Dictionary<string, Dictionary<string, List<PropertyValidatorInfo>>>, les clés du premier Dictionary correspondant au nom du Dto validé, et les clés du second Dictionary au nom des propriétés soumises à des règles de validation du précédent Dto.
    • L'ensemble des validateurs de FluentValidation sont récupérés dans le constructeur
    • Puis la méthode GetValidationDescriptors commence la construction du premier Dictionary avec comme clé les noms des Dto validés
    • Elle appelle ensuite la méthode GetPropertyValidationDescriptors pour récupérer un second Dictionary avec comme clé les noms des propriétés validés de chaque Dto
    • Puis enfin c'est la méthode GetPropertyValidatorInfo qui est appelée pour constituer notre Dto PropertyValidatorInfo

fluent-validation-validators-json-aspnetcore.png

En conclusion

Et voilà, après avoir mis en place ce système, nous disposons d'un endpoint nous retournant la description de chaque validation appliquée côté API. Il ne nous reste "plus" qu'à récupérer ces validations et à les interpréter côté Client, mais ce sera le sujet du prochain article, avec une implémentation en React

En attendant, j'espère que cet article aura pu vous donner des idées. Dans tous les cas, n'hésitez pas à me contacter sur Twitter @vivienfabing ou en commentaire, et que le code soit avec vous !

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus