Composant Validator de Symfony : valider un objet, lire les violations
Le composant Validator de Symfony applique à un objet les contraintes de sa classe et renvoie la liste des violations, pour un formulaire comme pour du code.
#[Route('/api/inscriptions', methods: ['POST'], format: 'json')] public function __invoke(Request $request, ValidatorInterface $validator): JsonResponse { $donnees = $request->toArray(); $inscription = new Inscription((string) ($donnees['email'] ?? ''), (string) ($donnees['pseudo'] ?? '')); $violations = $validator->validate($inscription); if (\count($violations) > 0) { throw new ValidationFailedException($inscription, $violations); // 422 depuis Symfony 8.2 } // … }
validate() renvoie une ConstraintViolationList : vide, l'objet est valide ; sinon, chaque violation donne son getPropertyPath() et son getMessage(). C'est le même service que sollicitent $form->isValid() et #[MapRequestPayload] : des règles posées sur l'entité valent partout, formulaire, API ou commande. Le piège : la plupart des contraintes ignorent les valeurs vides. #[Assert\Positive] accepte un prix null, c'est voulu pour pouvoir combiner les contraintes ; sans #[Assert\NotBlank] à côté, le prix vide passe la validation et c'est la base qui refuse l'enregistrement.
Les exercices font poser sur l'entité Plat les contraintes qui refusent un plat sans nom, un prix négatif ou un doublon, sans toucher au contrôleur ni au formulaire, puis valider à la main une inscription d'API et laisser remonter la ValidationFailedException, que Symfony 8.2 transforme en réponse 422 avec la liste des violations.
2 exercices font travailler cette notion, en écrivant du code dans le navigateur.
Dans les parcours
- Pas n'importe quoi dans l'assiette Symfony pour les devs PHP · chapitre 3 : Les parchemins de la taverne
Dans la Pratique
- Laisser remonter une ValidationFailedException Une ValidationFailedException non attrapée donne désormais une 422 avec la liste des violations : plus besoin de l'envelopper.