• 50 heures
  • Difficile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 27/02/2019

La sérialisation avec le composant Serializer de Symfony

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

 Nous avons vu comment travailler la sérialisation et la désérialisation de ressources avec JMS Serializer car ce cours se concentre sur l'utilisation de FOSRestBundle pour organiser l'ensemble d'une application Symfony exposant une API REST : en effet, l'intégration de JMSSerializer est facilité avec FOSRestBundle.

Voyons dès maintenant comment utiliser le composant Serializer de Symfony.

Travailler avec le composant Serializer de Symfony

Activer le Serializer de Symfony

Pour pouvoir utiliser le Serializer il faut l'activer en configuration. Dans le fichier  config.yml  se trouvant dans le dossier  app/config  il faut ajouter la configuration suivante :

framework:
    serializer:
        enabled: true

Sérialisation

Afin de ne pas impacter le code que nous avons écrit jusque là, nous allons créer une nouvelle ressource.

Nouvelle ressource : auteur

Créons l'entité  Author  dans le dossier  src/AppBundle/Entity :

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table()
 *
 */
class Author
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column
     */
    private $fullname;

    /**
     * @ORM\Column(type="text")
     */
    private $biography;

    /**
     * @ORM\OneToMany(targetEntity="Article", mappedBy="author", cascade={"persist"})
     */
    private $articles;

    public function __construct()
    {
        $this->articles = new ArrayCollection();
    }

    public function getFullname()
    {
        return $this->fullname;
    }

    public function setFullname($fullname)
    {
        $this->fullname = $fullname;
    }

    public function getBiography()
    {
        return $this->biography;
    }

    public function setBiography($biography)
    {
        $this->biography = $biography;
    }

    public function getArticles()
    {
        return $this->articles;
    }
}

Il faut mettre à jour la classe  AppBundle\Entity\Article  pour faire figurer la relation avec  Author  :

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table()
 *
 */
class Article
{
    //…

    /**
     * @ORM\ManyToOne(targetEntity="Author", cascade={"all"}, fetch="EAGER")
     */
    private $author;

    // …

    public function getAuthor()
    {
        return $this->author;
    }

    public function setAuthor(Author $author)
    {
        $this->author = $author;
    }
}

 Allons-y, créons dès maintenant notre controller en charge de la présentation d'un auteur. Il nous faut une classe  AuthorController  et l'action  showAuthor  :

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Author;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class AuthorController extends Controller
{
    /**
     * @Route("/authors/{id}", name="author_show")
     */
    public function showAction()
    {
        $article = $this->getDoctrine()->getRepository('AppBundle:Article')->findOneById(1);

        $author = new Author();
        $author->setFullname('Sarah Khalil');
        $author->setBiography('Ma super biographie.');
        $author->getArticles()->add($article);


        $data =  $this->get('serializer')->serialize($author, 'json');

        $response = new Response($data);
        $response->headers->set('Content-Type', 'application/json');

        return $response;
    }
}

L'utilisation du service Serializer est très simple : la méthodeserializeprend deux paramètres, les données à sérialiser (ici notre objet$author), et le format dans lequel nous souhaitons sérialiser (ici, du JSON).

Résultat de sérialisation de l'objet author
Résultat de sérialisation de l'objet author
Désérialisation

Pour la désérialisation, rien de bien compliqué ! Il s'agit simplement de faire appel à la méthode  deserialize  du service  serializer . Créons une nouvelle action en charge de la création d'un auteur :

<?php

namespace AppBundle\Controller;

//…
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;

class AuthorController extends Controller
{
    //…

    /**
     * @Route("/authors", name="author_create")
     * @Method({"POST"})
     */
    public function createAction(Request $request)
    {
        $data = $request->getContent();
        $author = $this->get('serializer')->deserialize($data, 'AppBundle\Entity\Author', 'json');

        $em = $this->getDoctrine()->getManager();
        $em->persist($author);
        $em->flush();

        return new Response('', Response::HTTP_CREATED);
    }
}

La méthode  deserialize  prend trois paramètres :

  • les données à désérialiser (celles envoyées par le client),

  • le type d'objet qu'il faut obtenir,

  • et le format des données à désérialiser.

Testons donc la désérialisation avec Postman :

Résultat de la désérialisation
Résultat de la désérialisation

 Plutôt que d'aller en base de données, je vous propose de modifier l'actionshowActionpour  aller directement chercher un auteur grâce à son ID via le ParamConverter de Doctrine :

<?php

namespace AppBundle\Controller;

// …

class AuthorController extends Controller
{
    /**
     * @Route("/authors/{id}", name="author_show")
     */
    public function showAction(Author $author)
    {
        $data =  $this->get('serializer')->serialize($author, 'json');

        $response = new Response($data);
        $response->headers->set('Content-Type', 'application/json');

        return $response;
    }

    // …
}

Nous sommes maintenant en mesure de vérifier qu'un auteur a été ajouté en base de données :

L'auteur a bien été ajouté en base de données
L'auteur a bien été ajouté en base de données

 

Voilà pour vos premiers pas avec le composant Serializer de Symfony.

Vous devez savoir qu'il est possible d'étendre le Serializer via deux éléments centraux :

  • le normalizer, une classe qui est en charge de la transformation d'un objet en un tableau ;

  • l'encoder, une classe qui est en charge de la transformation de la donnée normalisée (tableau) en une chaîne de caractères (json/xml).

Le composant gère déjà tout ce qu'il faut pour le JSON et l'XML. Ceci dit, si vous souhaitez manipuler d'autres formats, les normalizers et les encoders sont faits pour vous !

 

Pour aller plus loin, je vous invite à lire la documentation officielle de Symfony :

Je vous conseille aussi de jeter un coup d'oeil à l'excellente présentation de Grégoire Pineau au SymfonyLive Paris 2017 sur le sujet : Serializer.

Fin de la première partie

Nous avons vu les contraintes de REST, l'importance des ressources ainsi que la sérialisation de ces dernières. Il est important de retenir que tout ce que nous avons vu pourra être amplement simplifié avec l'utilisation du bundle FOSRestBundle. Néanmoins, il faut bien comprendre ce qu'il se passe afin de pouvoir répondre aux besoins plus complexes auxquels vous pourriez faire face dans des projets futurs.

Exemple de certificat de réussite
Exemple de certificat de réussite