La sérialisation avant la version 8.1 de Symfony nécessitait de nombreuses manipulations manuelles répétitives comme le montre l'élément suivant :

<?php

final readonly class GetMemoController
{
    public function __construct(private SerializerInterface $serializer) {
    }

    public function __invoke(): JsonResponse
    {
        $data = new Memo(1, 'Super titre', 'super contenu', new \DateTimeImmutable('now'));
        $serialized = $this->serializer->serialize($data, 'json');

        return JsonResponse::fromJsonString($serialized, JsonResponse::HTTP_CREATED);
    }
}

Il faut injecter le service de sérialisation avec SerializerInterface, appeler la méthode serialize, transformer les données soi même et s'assurer de retourner le bon type de réponse.

Avec Symfony 8.1 les choses sont simplifiées grâce à #[Serialize] qui permet de retirer tout le code répétitif et de sérialiser automatiquement les valeurs de retour d'un controlleur dans le format qui convient, en reprenant l'exemple d'au dessus, le code devient le suivant :

final readonly class GetMemoController
{
    #[Serialize]
    public function __invoke(): Memo
    {
        return new Memo(1, 'Super titre', 'super contenu', new \DateTimeImmutable('now'));
    }
}

Plus besoin d'injecter SerializerInterface, plus besoin non plus de changer manuellement le type de données car le système s'en occupe automatiquement.

Il est à noter qu'il est possible de passer différents paramètres qui sont :

  • code : Il permet de définir le code de statut HTTP de la réponse.
  • headers : Permet d'ajouter des en-têtes HTTP personnalisées sous forme d'un tableau.
  • context : Permet de contrôler la sérialisation en précisant par exemple des groupes de sérialisation, des formats de données etc.

Voici un exemple qui utilise les trois paramètres :

#[Serialize(
    code: 200,
    headers: [
        // Sécurité
        'X-Content-Type-Options' => 'nosniff',
        // Cache
        'Cache-Control' => 'private, max-age=600',
    ],
    context: [
        DateTimeNormalizer::FORMAT_KEY => 'd/m/Y'
    ]
)]

Pour plus d'informations, tout est disponsible sur le post de blog officiel.