Sérialisation avec jms/serializer-bundle

Installation

D:\webprojects\test-api-project>composer require jms/serializer-bundle
Using version ^3.4 for jms/serializer-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.3.*"

Prefetching 16 packages 
  - Downloading (100%)  

Package operations: 16 installs, 0 updates, 0 removals
  - Installing hoa/exception (1.17.01.16): Loading from cache
  - Installing hoa/event (1.17.01.13): Loading from cache
  - Installing hoa/consistency (1.17.05.02): Loading from cache
  - Installing hoa/visitor (2.17.01.16): Loading from cache
  - Installing hoa/ustring (4.17.01.16): Loading from cache
  - Installing hoa/protocol (1.17.01.14): Loading from cache
  - Installing hoa/zformat (1.17.01.10): Loading from cache
  - Installing hoa/iterator (2.17.01.10): Loading from cache
  - Installing hoa/compiler (3.17.08.08): Loading from cache
  - Installing hoa/regex (1.17.01.13): Loading from cache
  - Installing hoa/math (1.17.05.16): Loading from cache
  - Installing hoa/stream (1.17.02.21): Loading from cache
  - Installing hoa/file (1.17.07.11): Loading from cache
  - Installing jms/metadata (2.1.0): Loading from cache
  - Installing jms/serializer (3.3.0): Loading from cache
  - Installing jms/serializer-bundle (3.4.1): Loading from cache
Writing lock file
Generating autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 1 recipe (3bdaac2ac8821bc8af3d710ff51a1686)
  -  WARNING  jms/serializer-bundle (>=3.0): From github.com/symfony/recipes-contrib:master
    The recipe for this package comes from the "contrib" repository, which is open to community contributions.
    Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/jms/serializer-bundle/3.0

    Do you want to execute this recipe?
    [y] Yes
    [n] No
    [a] Yes for all packages, only for the current installation session
    [p] Yes permanently, never ask again for this project
    (defaults to n): y
  - Configuring jms/serializer-bundle (>=3.0): From github.com/symfony/recipes-contrib:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.

Usage

Sérialiser un objet

Trois points important

  1. Clause use : use JMS\Serializer\SerializerInterface;
  2. Injection : public function check(…, SerializerInterface $serializer )
  3. Sérialisation : $string = $serializer→serialize($objet, 'json');
<?php
namespace App\Controller;
...
use JMS\Serializer\SerializerInterface;
...
class CheckVersionController extends AbstractController
{
     /**
      * @Route("/api/checkv", name="api_checkversion")
      */
    public function check(Request $request, SerializerInterface $serializer )
    {
       // Création d'un objet
        $proj = new Projects();
        $proj->setName('Test');
 
        // Sérialisation de l'Objet
        $data = $serializer->serialize($proj, 'json');
 
        // Envois de la réponse
        $response = new Response($data);
        $response->headers->set('Content-Type', 'application/json');
        return $response;
    }
}

Politique d'exclusion dans l'Entity

Avec les annotations directement dans le fichier de l'Entity on peut exclure des properties de la sérialisation.

Ne pas oublier d'inclure l'usage des annotations pour la sérialisation dans le fichier de l'Entity avec
use JMS\Serializer\Annotation as Serializer;

Tout Exclure

Avec l'annotation @Serializer\ExclusionPolicy(“ALL”) :

  1. <?php
  2.  
  3. namespace App\Entity;
  4.  
  5. use Doctrine\ORM\Mapping as ORM;
  6. use JMS\Serializer\Annotation as Serializer;
  7.  
  8. /**
  9.  * @ORM\Entity(repositoryClass="App\Repository\ProjectsRepository")
  10.  * @Serializer\ExclusionPolicy("ALL")
  11.  */
  12. class Projects
  13. {

Exposer (inclure) une propertie

Quand tout a été exclu on peut exposer certaines properties avec l'annotation @Serializer\Expose (lignes 20 et 26) :

  1. <?php
  2. ...
  3. use JMS\Serializer\Annotation as Serializer;
  4.  
  5. /**
  6.  * @ORM\Entity(repositoryClass="App\Repository\ProjectsRepository")
  7.  * @Serializer\ExclusionPolicy("ALL")
  8.  */
  9. class Projects
  10. {
  11. /**
  12.   * @ORM\Id()
  13.   * @ORM\GeneratedValue()
  14.   * @ORM\Column(type="integer")
  15.   */
  16. private $id;
  17.  
  18. /**
  19.   * @ORM\Column(type="string", length=40)
  20.   * @Serializer\Expose
  21.   */
  22. private $name;
  23.  
  24. /**
  25.   * @ORM\Column(type="string", length=255)
  26.   * @Serializer\Expose
  27.   */
  28. private $url;

Utiliser des groupes

On peut utiliser des groupes, voir l'annotation @Serializer\Groups({“group1”, “group2”})

Il ne faut pas utiliser les groupes en même temps que les annotation Exclude et Expose.

Annotations dans le fichier de l'Entity

Pour chaque propertie on ajoute l'Annotation @Serializer\Groups({“Groupes d'appartenance”})

  1. <?php
  2. namespace App\Entity;
  3. use Doctrine\ORM\Mapping as ORM;
  4. use JMS\Serializer\Annotation as Serializer;
  5.  
  6. /**
  7.  * @ORM\Entity(repositoryClass="App\Repository\ProjectsRepository")
  8.  */
  9. class Projects
  10. {
  11. /**
  12.   * @ORM\Id()
  13.   * @ORM\GeneratedValue()
  14.   * @ORM\Column(type="integer")
  15.   * @Serializer\Groups({"all"})
  16.   */
  17. private $id;
  18.  
  19. /**
  20.   * @ORM\Column(type="string", length=40)
  21.   * @Serializer\Groups({"all"})
  22.   */
  23. private $name;
  24.  
  25. /**
  26.   * @ORM\Column(type="string", length=255)
  27.   * @Serializer\Groups({"all","version"})
  28.   */
  29. private $url;
  30.  
  31. /**
  32.   * @ORM\Column(type="integer")
  33.   * @Serializer\Groups({"all","version"})
  34.   */
  35. private $vmaj;
  36.  
  37. /**
  38.   * @ORM\Column(type="integer")
  39.   * @Serializer\Groups({"all","version"})
  40.   */
  41. private $vmin;
  42.  
  43. /**
  44.   * @ORM\Column(type="integer")
  45.   * @Serializer\Groups({"all","version"})
  46.   */
  47. private $revision;
  48.  
  49. /**
  50.   * @ORM\Column(type="integer")
  51.   * @Serializer\Groups({"all","version"})
  52.   */
  53. private $construction;
  54. ...

Modification du Controller

  1. (ligne 5) On rajoute la clause use JMS\Serializer\SerializationContext;
  2. (ligne 15) On rajoute le paramétre : SerializationContext::create()→setGroups(array('version')) a l'appel $serializer→serialize, ou version est le nom du groupe que l'on veut voir sérialiser.
  1. <?php
  2. namespace App\Controller;
  3. ...
  4. use JMS\Serializer\SerializerInterface;
  5. use JMS\Serializer\SerializationContext;
  6. ...
  7. class CheckVersionController extends AbstractController
  8. {
  9. /**
  10.   * @Route("/api/checkv/{projName}", name="api_checkVersion", methods={"GET"})
  11.   */
  12. public function check(Request $request, SerializerInterface $serializer, string $projName)
  13. {
  14. $proj = $this->getDoctrine()->getRepository('App:Projects')->findOneBy(['name' => $projName]);
  15. $data = $serializer->serialize($proj, 'json',SerializationContext::create()->setGroups(array('version')));

Autres Annotations

Utiliser les evenements

On peut utiliser les evenements :

  • serializer.pre_serialize : l'évènement est de type JMS\Serializer\EventDispatcher\PreSerializeEvent et permet de changer le type de l'objet à sérialiser. Il est également possible d'accéder aux données de l'objet à sérialiser, ainsi qu'au visiteur (objet utilisé pour parcourir l'objet à sérialiser).
  • serializer.post_serialize : l'évènement est de type JMS\Serializer\EventDispatcher\ObjectEvent et permet de modifier le résultat de la sérialisation de l'objet.
  • serializer.pre_deserialize : l'évènement est de type JMS\Serializer\EventDispatcher\PreDeserializeEvent et permet de modifier les données soumises à l'application et/ou modifier le type de l'objet à obtenir après désérialisation.
  • serializer.post_deserialize : l'évènement est de type JMS\Serializer\EventDispatcher\ObjectEvent et permet de faire des manipulations sur l'objet désérialisé comme de la validation ou ajouter des informations à l'objet qui pourrait provenir d'un service (API) externe par exemple.

Plus d'infos : https://openclassrooms.com/fr/courses/4087036-construisez-une-api-rest-avec-symfony/4302366-allez-plus-loin-avec-jmsserializer#/id/r-4302459

Utiliser un Handler

C'est a dire créer un méthode qui sera appelée «à la place» de la méthode serialize ou deserialize.
Ce qui laisse la maîtrise totale de la sérialisation ou dé-sérialisation…

Plus d'infos : https://openclassrooms.com/fr/courses/4087036-construisez-une-api-rest-avec-symfony/4302366-allez-plus-loin-avec-jmsserializer#/id/r-4302489

Voir aussi

Vous pourriez laisser un commentaire si vous étiez connecté.