Si une contrainte n’est pas respectée, API Platform renvoie une réponse 422 Unprocessable Entity avec les "violations".
Groupes de validation
Pourquoi les utiliser ?
Appliquer des règles différentes selon l’opération (POST vs PUT).
Éviter certaines validations selon le contexte.
Exemple pour valider certain chmaps sur le post et d'autre sur le PUT:
NB: le groupe Default contient les contraintes de la classe actuelle et de toutes les classes référencées qui n’appartiennent à aucun autre groupe. Dans cet exemple, il ne contient que le champ description.
Contraintes personnalisées
Créer une contrainte personnalisé est assez simple, et cela peut être pratique pour des validations avancées non prises en charge par Symfony.
Dans l'idée, une contrainte se compose de:
Constraint : définit le message et les options.
ConstraintValidator : contient la logique de validation.
Exemple simple :
CustomConstraint s'utilise désormais comme n'importe quelle contrainte.
Erreurs et format des violations
Quand la validation échoue, API Platform renvoie une structure de violations standard :
Cette réponse est formatée selon le format demandé (JSON‑LD par défaut).
Bonnes pratiques
Utiliser les groupes pour distinguer les règles selon l’opération (création/modification). (api-platform.com)
Personnaliser les messages pour fournir des retours clairs aux consommateurs de l’API.
Test unitaire / fonctionnel : ajouter des tests pour vérifier les contraintes.
Documenter les règles via OpenAPI/Swagger (API Platform les expose automatiquement).
<?php
....
use Symfony\Component\Validator\Constraints as Assert;
#[Post(
validationContext: ['groups' => ['Default', 'post']]
)]
#[Put(
validationContext: ['groups' => ['Default', 'put']]
)]
class Book
{
#[Assert\NotBlank(groups: ['post'])]
public string $title;
#[Assert\NotNull(groups: ['put'])]
public string $author;
#[Assert\NotNull]
public string $description;
}
// src/Validator/Constraints/CustomConstraint.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
#[\Attribute]
class CustomConstraint extends Constraint
{
public $message = 'Cette contrainte n\'est pas valide car ....';
}
// src/Validator/Constraints/CustomConstraintValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class CustomConstraintValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint): void
{
// do some test
if (false === $isValid) {
$this
->context
->buildViolation($constraint->message)
->addViolation();
}
}
}
{
"@type": "ConstraintViolationList",
"violations": [
{
"propertyPath": "name",
"message": "This value should not be blank."
}
]
}