veilletech.fr
2 oct. Feed du jour
#02 SYMFONY Article

Symfony 8.2 : un nom de champ par version d'API

Un champ renommé ne justifie plus un second DTO.

Symfony 8.2 assouplit les groupes de sérialisation : #[SerializedName] et #[SerializedPath] acceptent un argument groups, deux options de contexte excluent des groupes ou appliquent les groupes implicites du Validator, et les contrôleurs comme Messenger peuvent choisir un sérialiseur nommé. Un champ renommé en v2 n'exige plus un second DTO, et régler le sérialiseur de l'API ne change plus le format des messages.

2 min de lectureintermédiairevidéo 1:19
Partager
Sommaire6 sections
  1. Ce qui se passe
  2. Un nom ou un chemin par groupe
  3. Exclure un groupe au lieu d'une propriété
  4. La convention du Validator, sur option
  5. Un sérialiseur par usage
  6. À retenir

Ce qui se passe

Les groupes de sérialisation décident des propriétés qui sortent selon le contexte : un groupe pour l'API publique, un autre pour un export d'administration. Symfony 8.2 enrichit leur configuration sur trois points, et laisse les contrôleurs et Messenger choisir leur propre sérialiseur.

Un nom ou un chemin par groupe

Jusqu'ici, #[SerializedName] et #[SerializedPath] donnaient une clé unique à une propriété, quel que soit le groupe. Exposer la même donnée sous deux noms obligeait à dupliquer le DTO. Les deux attributs deviennent répétables et prennent un argument groups — contribution de Sergey Danilchenko. Esquisse pour une API dont la v2 a renommé un champ :

PHP
#[Groups(['api_v1', 'api_v2'])]
#[SerializedName('product_name', groups: ['api_v1'])]
public string $name;

Avec api_v1, la clé est product_name, à la sérialisation comme à la désérialisation. Un nom déclaré sans groupe sert de repli quand aucun des groupes demandés ne correspond. Le mapping YAML et XML suit.

Exclure un groupe au lieu d'une propriété

#[Ignore] exclut une propriété partout. L'option de contexte AbstractNormalizer::IGNORED_GROUPS (ignored_groups) retire seulement les propriétés des groupes listés : on garde un jeton pour un usage interne et on l'écarte des réponses HTTP. Avec les context builders, c'est withIgnoredGroups(). Contribution de zim32, PR #57166.

La convention du Validator, sur option

Dès qu'on sérialise avec des groupes, une propriété sans #[Groups] disparaît. Le Validator, lui, la range d'office dans Default et dans le groupe qui porte le nom de la classe, Book par exemple. L'option AbstractNormalizer::ENABLE_DEFAULT_GROUPS (enable_default_groups) apporte cette convention au Serializer — contribution de Bastien Clément. Elle ne joue que si aucun groupe personnalisé n'est demandé : avec ['groups' => ['admin']], la propriété non annotée reste dehors. On l'active pour toute l'application dans le contexte par défaut du sérialiseur.

Un sérialiseur par usage

Un sérialiseur nommé a ses propres normaliseurs, son convertisseur de noms et son contexte par défaut. Mais #[MapRequestPayload], #[MapQueryString], #[Serialize] et le transport messenger.transport.symfony_serializer passaient tous par le service serializer. Conséquence : régler l'API en snake_case modifiait au passage le format des messages en file. En 8.2, chacun peut désigner le sien (HypeMC, PR #66189 et #66192).

Une exception demeure : les réponses 422 des erreurs de validation utilisent toujours le sérialiseur par défaut, et leurs chemins de propriétés ignorent le convertisseur de noms du sérialiseur nommé.

Source : New in Symfony 8.2: More Flexible Serialization Groups, Symfony, 1er octobre 2026.