Modéliser le contrat backend
PHP est la source de vérité. Les types et la validation vivent sur l'entité, et tout le reste en découle.
<?php
class AlerteRecherche
{
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
#[ORM\Column]
private ?int $id = null; // privé et sans Groups : le Serializer l'ignore
#[Assert\NotBlank]
#[Assert\Count(min: 1)]
#[Groups(['alerte:read', 'alerte:create'])]
public array $canaux = [];
#[Assert\Email]
#[Groups(['alerte:create'])]
public ?string $email = null;
}