Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Serialización en Symfony con JMSSerializerBundle y el componente Serializer

Serialización en Symfony con JMSSerializerBundle y el componente Serializer

Tener un buen dominio de la serialización es algo fundamental para construir APIs limpias.

Tanto el componente Serializer de Symfony como el JMSSerializerBundle son dos herramientas muy potentes que nos facilitan la tarea de crear diferentes representaciones de nuestros modelos y crear o actualizar esos objetos a partir de sus representaciones.

En esta charla explicaremos cómo funcionan y cómo se utilizan tanto el componente como el bundle, veremos casos de uso interesantes y analizaremos qué fortalezas tiene cada uno de ellos y en qué ocasiones o para qué tareas concretas puede resultar más cómodo uno u otro. Todo ello enfocado desde un punto de vista práctico, con ejemplos que ayuden a ilustrar los distintos usos y situaciones.

Victoria Quirante

July 01, 2017
Tweet

More Decks by Victoria Quirante

Other Decks in Programming

Transcript

  1. View Slide

  2. View Slide

  3. Trabajo en Limenius
    Ofrecemos formación, consultoría y
    desarrollo a empresas
    Trabajamos con Symfony y React
    No hay proyecto que no tenga una API
    El serializador es uno de tus mejores
    amigos al implementar una API
    Victoria Quirante
    @vicqr
    [email protected]

    View Slide

  4. INTRODUCCIÓN
    De qué va todo esto
    http://www.flickr.com/photos/lilianasaeb/16463233379

    View Slide

  5. ¿Qué es serializar?

    View Slide

  6. @vicqr
    Serialización
    Es el proceso de codificación de un objeto en otro formato que
    puede ser almacenado, transmitido y posteriormente descodificado

    View Slide

  7. @vicqr
    Serialización
    Es el proceso de codificación de un objeto en otro formato que
    puede ser almacenado, transmitido y posteriormente descodificado
    OBJETOS REPRESENTACIONES
    (JSON, XML..)

    View Slide

  8. @vicqr
    Serialización
    Es el proceso de codificación de un objeto en otro formato que
    puede ser almacenado, transmitido y posteriormente descodificado
    OBJETOS REPRESENTACIONES
    (JSON, XML..)
    Serialización

    View Slide

  9. @vicqr
    Serialización
    Es el proceso de codificación de un objeto en otro formato que
    puede ser almacenado, transmitido y posteriormente descodificado
    OBJETOS REPRESENTACIONES
    (JSON, XML..)
    Serialización
    Deserialización

    View Slide

  10. @vicqr
    Ejemplo de serialización
    $responseData = [
    'id' => $spaceship->getId(),
    'name' => $spaceship->getName(),
    'color' => $spaceship->getColor(),
    'maxSpeed' => $spaceship->getMaxSpeed(),
    ];
    $response = new JsonResponse($responseData, 201);
    Nuestro objeto -> La response
    (serialización manual)

    View Slide

  11. @vicqr
    Ejemplo de serialización
    $responseData = [
    'id' => $spaceship->getId(),
    'name' => $spaceship->getName(),
    'color' => $spaceship->getColor(),
    'maxSpeed' => $spaceship->getMaxSpeed(),
    ];
    $response = new JsonResponse($responseData, 201);
    ...
    ...
    $spaceship = new Spaceship();
    $spaceship->setName($content['name']);
    $spaceship->setColor($content['color']);
    $spaceship->setMaxSpeed($content['maxSpeed']);
    Nuestro objeto -> La response
    (serialización manual)
    La request -> Nuestro objeto
    (deserialización manual)

    View Slide

  12. @vicqr
    Ejemplo de serialización
    $responseData = [
    'id' => $spaceship->getId(),
    'name' => $spaceship->getName(),
    'color' => $spaceship->getColor(),
    'maxSpeed' => $spaceship->getMaxSpeed(),
    ];
    $response = new JsonResponse($responseData, 201);
    ...
    ...
    $spaceship = new Spaceship();
    $spaceship->setName($content['name']);
    $spaceship->setColor($content['color']);
    $spaceship->setMaxSpeed($content['maxSpeed']);
    Apasionante :_(
    Nuestro objeto -> La response
    (serialización manual)
    La request -> Nuestro objeto
    (deserialización manual)

    View Slide

  13. @vicqr
    Serialización con serializador
    $responseData = [
    'id' => $spaceship->getId(),
    'name' => $spaceship->getName(),
    'color' => $spaceship->getColor(),
    'maxSpeed' => $spaceship->getMaxSpeed(),
    ];
    $response = new JsonResponse($responseData, 201);
    Convirtiendo nuestro objeto en una Response en JSON

    View Slide

  14. @vicqr
    Serialización con serializador
    $responseData = [
    'id' => $spaceship->getId(),
    'name' => $spaceship->getName(),
    'color' => $spaceship->getColor(),
    'maxSpeed' => $spaceship->getMaxSpeed(),
    ];
    $response = new JsonResponse($responseData, 201);
    --------------
    $response = new Response($serializer->serialize($spaceship, 'json'), 201);
    Convirtiendo nuestro objeto en una Response en JSON

    View Slide

  15. @vicqr
    Deserialización con serializador
    $spaceship = new Spaceship();
    $spaceship->setName($content['name']);
    $spaceship->setColor($content['color']);
    $spaceship->setMaxSpeed($content['maxSpeed']);
    Convirtiendo el contenido de la Request (JSON) en un objeto

    View Slide

  16. @vicqr
    Deserialización con serializador
    $spaceship = new Spaceship();
    $spaceship->setName($content['name']);
    $spaceship->setColor($content['color']);
    $spaceship->setMaxSpeed($content['maxSpeed']);
    ------------------
    $spaceship = $serializer->deserialize($content, Spaceship::class, 'json');
    Convirtiendo el contenido de la Request (JSON) en un objeto

    View Slide

  17. ¿A qué llamamos
    serializador?

    View Slide

  18. @vicqr
    El serializador
    Es un código que es muy bueno serializando por nosotros

    View Slide

  19. @vicqr
    El serializador
    Es un código que es muy bueno serializando por nosotros

    View Slide

  20. El verdadero problema
    que nos ayuda a resolver

    View Slide

  21. Los objetos y las representaciones que
    queremos pueden ser muy distintos

    View Slide

  22. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }

    View Slide

  23. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”

    View Slide

  24. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo

    View Slide

  25. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    No quiero mostrarlo en el list

    View Slide

  26. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    No quiero mostrarlo en el list
    Quiero añadir “thumb_”

    View Slide

  27. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    No quiero mostrarlo en el list
    Quiero añadir “thumb_”
    Solo en la versión 2 de la API

    View Slide

  28. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    No quiero mostrarlo en el list
    Quiero añadir “thumb_”
    Solo en la versión 2 de la API
    Quiero que sea un campo más

    View Slide

  29. @vicqr
    Representaciones != lo que hay en la BD
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    No quiero mostrarlo en el list
    Quiero añadir “thumb_”
    Solo en la versión 2 de la API
    Quiero que sea un campo más
    Con este tipo de cosas es con lo que va a ayudarnos un serializador

    View Slide

  30. VISTAZO GENERAL
    A ambas soluciones

    View Slide

  31. @vicqr
    Datos básicos
    JMSSERIALIZERBUNDLE SYMFONY SERIALIZER

    View Slide

  32. @vicqr
    Datos básicos
    JMSSERIALIZERBUNDLE
    - Es un bundle (y librería, claro)
    - Creado por @schmittjoh
    - Se comenzó en abril de 2011
    - Pasó época de poco mantenimiento
    - Desde hace un año mejor
    (@goetas_asmir)
    - Licencia Apache
    SYMFONY SERIALIZER

    View Slide

  33. @vicqr
    Datos básicos
    JMSSERIALIZERBUNDLE SYMFONY SERIALIZER
    - Es un bundle (y librería, claro)
    - Creado por @schmittjoh
    - Se comenzó en abril de 2011
    - Pasó época de poco mantenimiento
    - Desde hace un año mejor
    (@goetas_asmir)
    - Licencia Apache
    - Es un Symfony Component
    - Desarrollado por los core
    - Se comenzó en enero de 2011
    - Se le criticaba que “le faltan
    muchas cosas”
    - En continua evolución y mejora
    - Licencia MIT

    View Slide

  34. @vicqr
    Inciso: componentes y bundles
    - Componente -> librería desacoplada y reutilizable
    - Bundle -> atado al Symfony Framework

    View Slide

  35. @vicqr
    Inciso: componentes y bundles
    - Componente -> librería desacoplada y reutilizable
    - Bundle -> atado al Symfony Framework
    A menudo tenemos:
    Funcionalidad
    Librería
    Integración con SF
    Configuración
    Inyección de dependencias
    Bundle
    +

    View Slide

  36. @vicqr
    Inciso: componentes y bundles
    - Componente -> librería desacoplada y reutilizable
    - Bundle -> atado al Symfony Framework
    A menudo tenemos:
    Por ejemplo, en el caso del JMSSerializerBundle
    Funcionalidad
    Librería
    Integración con SF
    Configuración
    Inyección de dependencias
    Bundle
    +

    View Slide

  37. @vicqr
    JMSSerialiazerBundle - Características
    - Muchas anotaciones útiles
    que cubren casos de uso
    muy frecuentes
    - Muy sencillo empezar a
    utilizarlo

    View Slide

  38. @vicqr
    JMSSerialiazer - Instalación y setup
    - Instalación:
    - composer require
    - Registrar el bundle
    http://jmsyst.com/bundles/JMSSerializerBundle

    View Slide

  39. @vicqr
    JMSSerialiazer - Instalación y setup
    - Instalación:
    - composer require
    - Registrar el bundle
    - Setup: no hay que hacer nada para empezar a usarlo
    http://jmsyst.com/bundles/JMSSerializerBundle

    View Slide

  40. @vicqr
    Componente Serializer - Características
    - No aspira a resolver casos
    de uso concretos sino a
    proporcionar una
    arquitectura que te permita
    hacerlo
    - Menos “ya hecho”, más
    flexible
    Aproximación diferente

    View Slide

  41. @vicqr
    Componente Serializer - Características

    View Slide

  42. @vicqr
    Componente Serializer - Características
    El trabajo más complejo se lleva a cabo en los normalizadores

    View Slide

  43. @vicqr
    SF Serializer - Instalación y setup
    - Instalación:
    - composer require
    - Si quieres usar ObjectNormalizer instalas también PropertyAccess

    View Slide

  44. @vicqr
    SF Serializer - Instalación y setup
    - Instalación:
    - composer require
    - Si quieres usar ObjectNormalizer instalas también PropertyAccess
    - Setup: hay que hacer algunas cosas

    View Slide

  45. @vicqr
    Componente Serializer - Setup
    use Symfony\Component\Serializer\Serializer;
    use Symfony\Component\Serializer\Encoder\XmlEncoder;
    use Symfony\Component\Serializer\Encoder\JsonEncoder;
    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
    $encoders = array(new XmlEncoder(), new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    serializer = new Serializer($normalizers, $encoders);

    View Slide

  46. @vicqr
    Componente Serializer - Setup
    use Symfony\Component\Serializer\Serializer;
    use Symfony\Component\Serializer\Encoder\XmlEncoder;
    use Symfony\Component\Serializer\Encoder\JsonEncoder;
    use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
    $encoders = array(new XmlEncoder(), new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    serializer = new Serializer($normalizers, $encoders);
    El ObjectNormalizer es muy potente, pero no idóneo para todos los casos

    View Slide

  47. TRABAJANDO CON AMBOS
    Serialicemos algo fácil

    View Slide

  48. http://github.com/VictoriaQ/sf-serialization-talk

    View Slide

  49. @vicqr
    JMSSerialiazerBundle - Deserialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships")
    * @Method("POST")
    */
    public function newAction(Request $request)
    {
    $serializer = $this->container->get('jms_serializer');
    $spaceship = $serializer->deserialize($request->getContent(), Spaceship::class, 'json');
    $em = $this->getDoctrine()->getManager();
    $em->persist($spaceship);
    $em->flush();
    return new Response("Spaceship created!");
    }

    View Slide

  50. @vicqr
    JMSSerialiazerBundle - Deserialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships")
    * @Method("POST")
    */
    public function newAction(Request $request)
    {
    $serializer = $this->container->get('jms_serializer');
    $spaceship = $serializer->deserialize($request->getContent(), Spaceship::class, 'json');
    $em = $this->getDoctrine()->getManager();
    $em->persist($spaceship);
    $em->flush();
    return new Response("Spaceship created!");
    }

    View Slide

  51. @vicqr
    JMSSerialiazerBundle - Serialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships/{name}")
    * @Method("GET")
    */
    public function showAction($name)
    {
    $spaceship = $this->getDoctrine()
    ->getRepository('AppBundle:Spaceship')
    ->findOneByName($name);
    $serializer = $this->container->get('jms_serializer');
    return new Response($serializer->serialize($spaceship, 'json'), 200);
    }

    View Slide

  52. @vicqr
    JMSSerialiazerBundle - Serialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships/{name}")
    * @Method("GET")
    */
    public function showAction($name)
    {
    $spaceship = $this->getDoctrine()
    ->getRepository('AppBundle:Spaceship')
    ->findOneByName($name);
    $serializer = $this->container->get('jms_serializer');
    return new Response($serializer->serialize($spaceship, 'json'), 200);
    }

    View Slide

  53. @vicqr
    JMSSerialiazerBundle - Serialización
    HTTP/1.1 200 OK
    Host: localhost:8000
    Connection: close
    X-Powered-By: PHP/7.1.0-0ubuntu0.16.04.4
    Cache-Control: no-cache, private
    Date: Sat, 24 Jun 2017 17:45:32 GMT
    Content-Type: application/json
    X-Debug-Token: 127f2b
    X-Debug-Token-Link: http://localhost:8000/_profiler/127f2b
    {"id":1,"name":"Orion","color":"Razzmic Berry","maxSpeed":8900}

    View Slide

  54. @vicqr
    Componente Serializer - Deserialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships")
    * @Method("POST")
    */
    public function newAction(Request $request)
    {
    $encoders = array(new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    $serializer = new Serializer($normalizers, $encoders);
    $spaceship = $serializer->deserialize($request->getContent(), Spaceship::class, 'json');
    $em = $this->getDoctrine()->getManager();
    $em->persist($spaceship);
    $em->flush();
    return new Response("Spaceship created!");
    }

    View Slide

  55. @vicqr
    Componente Serializer - Deserialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships")
    * @Method("POST")
    */
    public function newAction(Request $request)
    {
    $encoders = array(new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    $serializer = new Serializer($normalizers, $encoders);
    $spaceship = $serializer->deserialize($request->getContent(), Spaceship::class, 'json');
    $em = $this->getDoctrine()->getManager();
    $em->persist($spaceship);
    $em->flush();
    return new Response("Spaceship created!");
    }

    View Slide

  56. @vicqr
    Deserializar un objeto ya existente
    # AppBundle/Controller/Api/SpaceshipController.php
    $serializer->deserialize($request->getContent(), Spaceship::class, 'json',
    array('object_to_populate' => $spaceship));

    View Slide

  57. @vicqr
    Componente Serializer - Serialización
    # AppBundle/Controller/Api/SpaceshipController.php
    /**
    * @Route("/api/spaceships/{name}")
    * @Method("GET")
    */
    public function showAction($name)
    {
    $encoders = array(new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    $serializer = new Serializer($normalizers, $encoders);
    $spaceship = $this->getDoctrine()
    ->getRepository('AppBundle:Spaceship')
    ->findOneByName($name);
    return new Response($serializer->serialize($spaceship, 'json'), 200);
    }

    View Slide

  58. @vicqr
    Comparación inicial
    Algo de instalación -mínimo- el bundle
    Algo más de configuración el componente
    En general, para este tipo de ejemplo, idéntico uso

    View Slide

  59. @vicqr
    Comparación inicial
    Algo de instalación -mínimo- el bundle
    Algo más de configuración el componente
    En general, para este tipo de ejemplo, idéntico uso
    Pero este tipo de ejemplo no existe

    View Slide

  60. JMSSERIALIZERBUNDLE
    EN DETALLE
    http://www.flickr.com/photos/florianric/7263382550

    View Slide

  61. @vicqr
    JMSSerializerBundle
    Tres estrategias de exclusión (Exclude, Groups, Versions)
    Propiedades configurables (Virtual Props., Accessors)
    Eventos para más flexibilidad
    XML muy configurable
    Muchas funcionalidades que necesitas siempre listas para usar

    View Slide

  62. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose

    View Slide

  63. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose
    - Versiones: @Until, @Since

    View Slide

  64. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose
    - Versiones: @Until, @Since
    - Diferentes vistas de un objeto: @Groups

    View Slide

  65. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose
    - Versiones: @Until, @Since
    - Diferentes vistas de un objeto: @Groups
    - Limitar nivel de serialización en el grafo: @MaxDepth

    View Slide

  66. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose
    - Versiones: @Until, @Since
    - Diferentes vistas de un objeto: @Groups
    - Limitar nivel de serialización en el grafo: @MaxDepth
    - Exclusión dinámica: @Exclude(if=”...”)

    View Slide

  67. @vicqr
    Estrategias de exclusión
    - Estrategias generales: @ExclusionPolicy (all, none), @Exclude, @Expose
    - Versiones: @Until, @Since
    - Diferentes vistas de un objeto: @Groups
    - Limitar nivel de serialización en el grafo: @MaxDepth
    - Exclusión dinámica: @Exclude(if=”...”)
    Muchas formas de indicar qué propiedades muestras y cuáles no

    View Slide

  68. @vicqr
    Propiedades configurables
    - Cambiar nombre de una propiedad: @SerializedName
    - Crear propiedades virtuales: @VirtualProperty

    View Slide

  69. @vicqr
    Propiedades configurables
    - Cambiar nombre de una propiedad: @SerializedName
    - Crear propiedades virtuales: @VirtualProperty
    Sencillo cambiar lo que tengo por defecto en las propiedades

    View Slide

  70. @vicqr
    Accessors
    - De qué modo hay que acceder las propiedades: @AccessorType
    - Qué método hay que utilizar para acceder una propiedad: @Accessor
    - En qué orden hay que acceder las propiedades: @AccessorOrder

    View Slide

  71. @vicqr
    Accessors
    - De qué modo hay que acceder las propiedades: @AccessorType
    - Qué método hay que utilizar para acceder una propiedad: @Accessor
    - En qué orden hay que acceder las propiedades: @AccessorOrder
    Sencillo configurar el acceso a las propiedades

    View Slide

  72. @vicqr
    XML muy configurable
    - @XmlRoot
    - @XmlAttribute
    - @XmlDiscriminator
    - @XmlValue
    - @XmlList
    - @XmlMap
    - @XmlKeyValuePairs
    - @XmlAttributeMap
    - @XmlElement
    - @XmlNamespace

    View Slide

  73. @vicqr
    XML muy configurable
    - @XmlRoot
    - @XmlAttribute
    - @XmlDiscriminator
    - @XmlValue
    - @XmlList
    - @XmlMap
    - @XmlKeyValuePairs
    - @XmlAttributeMap
    - @XmlElement
    - @XmlNamespace
    Hay consenso en que para trabajar con XML es estupendo

    View Slide

  74. @vicqr
    Eventos para mayor customización
    - serializer.pre_serialize
    - serializer.post_serialize
    - serializer.pre_deserialize
    - serializer.post_deserialize

    View Slide

  75. @vicqr
    Eventos para mayor customización
    - serializer.pre_serialize
    - serializer.post_serialize
    - serializer.pre_deserialize
    - serializer.post_deserialize
    Por ej., para utilizar un servicio (al que no puedes llamar desde la Entidad)
    http://knpuniversity.com/screencast/symfony-rest3/serialization-event-subscriber

    View Slide

  76. @vicqr
    Suscribers
    Los eventos tienen un getVisitor()
    El visitor es el encargado del proceso de serialización
    Utilizando $visitor->addData() podemos añadir los campos que queramos

    View Slide

  77. @vicqr
    Suscribers
    Los eventos tienen un getVisitor()
    El visitor es el encargado del proceso de serialización
    Utilizando $visitor->addData() podemos añadir los campos que queramos
    Esta forma de trabajar no encaja mucho con la filosofía del componente Serializer

    View Slide

  78. @vicqr
    Deserializando objetos complejos
    Utilizamos la anotación @Type para que el serializer sepa qué objeto
    es cada uno

    View Slide

  79. @vicqr
    Algún detalle que viene bien saber
    - Hay que solucionar el problema del underscore
    # app/config/config.yml
    parameters:
    jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy

    View Slide

  80. @vicqr
    Algún detalle que viene bien saber
    - Hay que solucionar el problema del underscore
    # app/config/config.yml
    parameters:
    jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy
    https://knpuniversity.com/screencast/symfony-rest

    View Slide

  81. @vicqr
    Algún detalle que viene bien saber
    - Hay que solucionar el problema del underscore
    # app/config/config.yml
    parameters:
    jms_serializer.camel_case_naming_strategy.class: JMS\Serializer\Naming\IdenticalPropertyNamingStrategy
    - Los campos null por defecto no se serializan
    # src/AppBundle/Controller/Api/SpaceshipController.php
    $context = new SerializationContext();
    $context->setSerializeNull(true);
    return $this->container->get('jms_serializer')->serialize($data, $format, $context);
    https://knpuniversity.com/screencast/symfony-rest

    View Slide

  82. @vicqr
    Críticas y elogios frecuentes
    - Problema licencia
    - Mantenimiento regular
    - Modelo “caja de herramientas”

    View Slide

  83. @vicqr
    Críticas y elogios frecuentes
    - Problema licencia
    - Mantenimiento regular
    - Modelo “caja de herramientas”
    - Fácil de usar
    - Permite resolver problemas muy habituales muy cómodamente

    View Slide

  84. COMPONENTE SERIALIZER
    EN DETALLE

    View Slide

  85. @vicqr
    Componente Serializer
    No pretende darte soluciones ya hechas para todo
    Solo dos anotaciones (MaxDepth y Groups)
    Te proporciona algunos normalizadores muy útiles
    Va mucho de crear tus propios normalizadores
    Arquitectura potente y flexible que te permite exportar tus estructuras PHP

    View Slide

  86. @vicqr
    Anotaciones
    MaxDepth
    - Detecta y limita el nivel de serialización
    - Especialmente útil serializando árboles grandes

    View Slide

  87. @vicqr
    Anotaciones
    MaxDepth
    - Detecta y limita el nivel de serialización
    - Especialmente útil serializando árboles grandes
    Groups
    - Para serializar distintos grupos de atributos de tus entidades
    - De hecho sirve para implementar cualquiera de los métodos de exclusión

    View Slide

  88. @vicqr
    Anotaciones - Groups
    class Spaceship
    {
    /**
    * @Groups({"show", "list"})
    */
    public $name;
    /**
    * @Groups({"show"})
    */
    public $color;
    /**
    * @Groups({"show", "list"})
    */
    public $maxSpeed;
    }

    View Slide

  89. @vicqr
    Anotaciones - Groups
    class Spaceship
    {
    /**
    * @Groups({"show", "list"})
    */
    public $name;
    /**
    * @Groups({"show"})
    */
    public $color;
    /**
    * @Groups({"show", "list"})
    */
    public $maxSpeed;
    }

    View Slide

  90. @vicqr
    Anotaciones - Groups
    $groups = ['groups' => ['list']];
    $response = new Response($serializer->serialize($spaceship, 'json', $groups), 201);
    $response->headers->set('Content-Type', 'application/json');
    return $response;
    Así indicamos que queremos serializar el grupo show

    View Slide

  91. @vicqr
    Setup anotaciones
    use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
    use Doctrine\Common\Annotations\AnnotationReader;
    use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new
    AnnotationReader()));
    $normalizer = new ObjectNormalizer($classMetadataFactory);
    Hay que inicializar classMetadataFactory y pasárselo al normalizador

    View Slide

  92. @vicqr
    Habilitar cache de Doctrine
    # app/config/config_prod.yml
    framework:
    serializer:
    cache: serializer.mapping.cache.apc
    El sistema de extracción de metadatos es lento, conviene mucho
    habilitar la cache cuando se utilizan anotaciones (como Groups)

    View Slide

  93. @vicqr
    Los principales normalizers disponibles
    ObjectNormalizer:
    - El más completo
    - Utiliza el PropertyAccess Component para leer y escribir en el objeto
    - Normaliza a partir de los métodos get/set/has/remove del objeto

    View Slide

  94. @vicqr
    Los principales normalizers disponibles
    ObjectNormalizer:
    - El más completo
    - Utiliza el PropertyAccess Component para leer y escribir en el objeto
    - Normaliza a partir de los métodos get/set/has/remove del objeto
    GetSetMethodNormalizer:
    - Más sencillo que el anterior
    - Normaliza llamando a los getters y setters del objeto

    View Slide

  95. @vicqr
    Los principales normalizers disponibles
    ObjectNormalizer:
    - El más completo
    - Utiliza el PropertyAccess Component para leer y escribir en el objeto
    - Normaliza a partir de los métodos get/set/has/remove del objeto
    GetSetMethodNormalizer:
    - Más sencillo que el anterior
    - Normaliza llamando a los getters y setters del objeto
    PropertyNormalizer:
    - Normaliza leyendo directamente las propiedades del objeto

    View Slide

  96. @vicqr
    Los principales normalizers disponibles
    ObjectNormalizer:
    - El más completo
    - Utiliza el PropertyAccess Component para leer y escribir en el objeto
    - Normaliza a partir de los métodos get/set/has/remove del objeto
    GetSetMethodNormalizer:
    - Más sencillo que el anterior
    - Normaliza llamando a los getters y setters del objeto
    PropertyNormalizer:
    - Normaliza leyendo directamente las propiedades del objeto
    Todos devuelven un mapeo entre valores y
    nombres de propiedades, la diferencia es
    cómo lo obtienen

    View Slide

  97. @vicqr
    Los principales normalizers disponibles
    ObjectNormalizer:
    - El más completo
    - Utiliza el PropertyAccess Component para leer y escribir en el objeto
    - Normaliza a partir de los métodos get/set/has/remove del objeto
    GetSetMethodNormalizer:
    - Más sencillo que el anterior
    - Normaliza llamando a los getters y setters del objeto
    PropertyNormalizer:
    - Normaliza leyendo directamente las propiedades del objeto
    https://symfony.com/doc/current/components/serializer.html#normalizers
    Todos devuelven un mapeo entre valores y
    nombres de propiedades, la diferencia es
    cómo lo obtienen

    View Slide

  98. @vicqr
    ObjectNormalizer
    Es muy útil, pero también tiene un coste
    Se apoya en el PropertyAccess Component
    Ha sido bastante optimizado y siguen optimizándolo

    View Slide

  99. @vicqr
    ObjectNormalizer
    Es muy útil, pero también tiene un coste
    Se apoya en el PropertyAccess Component
    Ha sido bastante optimizado y siguen optimizándolo
    Si la performance importa, mejor utilizar GetSetMethodNormalizer,
    PropertyNormalizer o el tuyo propio

    View Slide

  100. @vicqr
    PropertyAccess Component
    http://symfony.com/doc/current/components/property_access.html
    Permite leer de y escribir en un objeto de forma cómoda
    Bien mediante propiedades públicas, setters/getters, hassers/issers
    Es esto concretamente lo que están intentando optimizar más

    View Slide

  101. Utilizar el Symfony
    Serializer va mucho de
    crear tus propios
    normalizadores

    View Slide

  102. @vicqr
    Creando tus normalizadores
    use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
    class OrgPrefixNameConverter implements NameConverterInterface
    {
    public function normalize($propertyName)
    {
    return 'apolo18_'.$propertyName;
    }
    public function denormalize($propertyName)
    {
    // remove prefix_ prefix
    return 'apolo18_' === substr($propertyName, 0, 8) ? substr($propertyName, 8) : $propertyName;
    }
    }
    Por ejemplo, para serializar atributos con un nombre distinto

    View Slide

  103. @vicqr
    Algunas funcionalidades secundarias
    - setIgnoredAttributes
    - Boolean functions (is, has)
    - Callbacks
    Para no serializar algunas propiedades
    Métodos cuyo resultado booleano se serializa
    Forma posible de formatear una propiedad

    View Slide

  104. @vicqr
    Algunas funcionalidades secundarias
    - setIgnoredAttributes
    - Boolean functions (is, has)
    - Callbacks
    Para no serializar algunas propiedades
    Métodos cuyo resultado booleano se serializa
    Forma posible de formatear una propiedad
    Están bien, pero no son imprescindibles

    View Slide

  105. @vicqr
    Callbacks
    $callback = function ($logoPath) {
    return 'thumb_'.$logoPath;
    };
    $normalizer->setCallbacks(array('logo' => $callback));
    Para formatear una propiedad del objeto (por ejemplo, fechas)

    View Slide

  106. @vicqr
    Referencias circulares
    Si no haces nada verás un error como este:
    A circular reference has been detected (configured limit: 1). (500 Internal Server Error)

    View Slide

  107. @vicqr
    Referencias circulares
    Si no haces nada verás un error como este:
    $normalizer->setCircularReferenceLimit(1);
    Número de veces que tiene que serializar un
    objeto antes de considerarlo referencia circular
    A circular reference has been detected (configured limit: 1). (500 Internal Server Error)

    View Slide

  108. @vicqr
    Referencias circulares
    Si no haces nada verás un error como este:
    $normalizer->setCircularReferenceLimit(1);
    $normalizer->setCircularReferenceHandler(function ($object) {
    return $object->getName();
    });
    Número de veces que tiene que serializar un
    objeto antes de considerarlo referencia circular
    En lugar de lanzar excepción, la referencia
    circular es gestionada por este callable
    A circular reference has been detected (configured limit: 1). (500 Internal Server Error)

    View Slide

  109. @vicqr
    Deserializando objetos complejos
    El Serializer utiliza el componente PropertyInfo para esto

    View Slide

  110. @vicqr
    PropertyInfo Component
    Extrae información de las propiedades de una clase PHP por a partir
    de metadatos (de Doctrine, PHP Reflection, PHP doc., etc.)

    View Slide

  111. @vicqr
    Deserializando objetos complejos
    El Serializer utiliza el componente PropertyInfo para esto
    Hay que pasarle un Extractor al normalizador

    View Slide

  112. @vicqr
    Deserializando objetos complejos
    El Serializer utiliza el componente PropertyInfo para esto
    Hay que pasarle un Extractor al normalizador
    use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
    $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());

    View Slide

  113. @vicqr
    Deserializando objetos complejos
    El Serializer utiliza el componente PropertyInfo para esto
    Hay que pasarle un Extractor al normalizador
    use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
    $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
    El Extractor indica de qué modo hay que extraer la información, el PropertyInfo permite al
    normalizador conocer el tipo de lo que tiene que desnormalizar

    View Slide

  114. @vicqr
    Críticas y elogios frecuentes
    - Ciertas cosas muy comunes son menos directas que en JMS
    - XML mal (pobre)

    View Slide

  115. ¿Y por qué lo del XML no
    está “bien hecho” en el
    Serializer?

    View Slide

  116. @vicqr
    ¿Por qué es pobre el XML?
    El XML puede ser bastante más rico que el JSON
    (namespaces, xincludes, instrucciones de procesado)…

    View Slide

  117. @vicqr
    ¿Por qué es pobre el XML?
    El XML puede ser bastante más rico que el JSON
    (namespaces, xincludes, instrucciones de procesado)…
    Añadir información de un formato a otro no encaja con la filosofía
    del Serializer

    View Slide

  118. «We want different representations of the same data structure
    without enrichment during the serialization process»
    Kevin Dunglas
    https://github.com/symfony/symfony/issues/19330#issuecomment-233515204

    View Slide

  119. @vicqr
    Críticas y elogios frecuentes
    - Ciertas cosas muy comunes son menos directas que en JMS
    - XML mal (pobre)

    View Slide

  120. @vicqr
    Críticas y elogios frecuentes
    - Ciertas cosas muy comunes son menos directas que en JMS
    - XML mal (pobre)
    - Flexible, fácil de extender
    - Potente, permite cubrir necesidades complejas de tu lógica de
    negocio
    - Bien mantenido

    View Slide

  121. @vicqr
    Ha ido mejorando y pretende seguir
    - Por ejemplo, algunas mejoras recientes:
    - DateTime Normalizer
    - Data URI Normalizer
    - CSV y YAML encoders

    View Slide

  122. @vicqr
    Ha ido mejorando y pretende seguir
    - Por ejemplo, algunas mejoras recientes:
    - DateTime Normalizer
    - Data URI Normalizer
    - CSV y YAML encoders
    - Conversación continua acerca de cómo mejorar:
    - http://github.com/symfony/symfony/issues/16179
    - http://github.com/symfony/symfony/issues/19330
    - http://github.com/symfony/symfony/pull/19374

    View Slide

  123. @vicqr
    Ha ido mejorando y pretende seguir
    - Por ejemplo, algunas mejoras recientes:
    - DateTime Normalizer
    - Data URI Normalizer
    - CSV y YAML encoders
    - Conversación continua acerca de cómo mejorar:
    - http://github.com/symfony/symfony/issues/16179
    - http://github.com/symfony/symfony/issues/19330
    - http://github.com/symfony/symfony/pull/19374
    - API Platform lo usa

    View Slide

  124. @vicqr
    Ha ido mejorando y pretende seguir
    - Por ejemplo, algunas mejoras recientes:
    - DateTime Normalizer
    - Data URI Normalizer
    - CSV y YAML encoders
    - Conversación continua acerca de cómo mejorar:
    - http://github.com/symfony/symfony/issues/16179
    - http://github.com/symfony/symfony/issues/19330
    - http://github.com/symfony/symfony/pull/19374
    - API Platform lo usa
    Las perspectivas son muy buenas

    View Slide

  125. Serialicemos algo menos fácil
    TRABAJANDO CON AMBOS

    View Slide

  126. @vicqr
    Serialicemos nuestra misión espacial
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    Quiero llamarlo “mission”
    No quiero mostrarlo
    Quiero mostrarlo en el list
    Quiero añadir “thumb_”
    Solo en la versión 2 de la API
    Quiero que sea un campo más

    View Slide

  127. @vicqr
    Serialicemos nuestra misión espacial
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    {
    mission: "Apolo18",
    email: "[email protected]",
    logo: "thumb_logo.jpg",
    spaceship: "Orion"
    }
    En el show

    View Slide

  128. @vicqr
    Serialicemos nuestra misión espacial
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    {
    mission: "Apolo18",
    email: "[email protected]",
    logo: "thumb_logo.jpg",
    spaceship: "Orion"
    }
    En el list

    View Slide

  129. @vicqr
    Serialicemos nuestra misión espacial
    {
    id: 18,
    name: "Apolo18",
    budget: "USD 6 billion",
    email: "[email protected]",
    logo: "logo.jpg",
    twitter: "apolo18",
    spaceship: {
    id: 29,
    name: "Orion"
    }
    }
    {
    mission: "Apolo18",
    email: "[email protected]",
    logo: "thumb_logo.jpg",
    twitter: "apolo18",
    spaceship: "Orion"
    }
    En la versión 2

    View Slide

  130. @vicqr
    Serialicemos nuestra misión espacial
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre

    View Slide

  131. @vicqr
    Con JMSSerializerBundle
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre
    @SerializedName
    @ExclusionStrategy, etc.
    @Groups
    @Accesor
    @Until, @Since
    @VirtualProperty

    View Slide

  132. @vicqr
    Con JMSSerializerBundle
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre
    @SerializedName
    @ExclusionStrategy, etc.
    @Groups
    @Accesor
    @Until, @Since
    @VirtualProperty
    No hay problema
    @Type
    - ¿Serializar objetos encadenados?
    - ¿Deserializar objetos encadenados?

    View Slide

  133. @vicqr
    Con Symfony Serializer
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre
    Un getter nuevo
    @Groups
    @Groups
    Un getter nuevo
    @Groups
    Un getter nuevo

    View Slide

  134. @vicqr
    Con Symfony Serializer
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre
    Un getter nuevo
    @Groups
    @Groups
    Un getter nuevo
    @Groups
    Un getter nuevo
    O escribir tus normalizers, cuando quieras

    View Slide

  135. @vicqr
    Con Symfony Serializer
    - Renombrar propiedades
    - Exponer solo las que quiero
    - Tener distintas representaciones
    - Modificar el valor de una propiedad
    - Tener distintas versiones de la API
    - Que spaceship sea solo un nombre
    Un getter nuevo
    @Groups
    @Groups
    Un getter nuevo
    @Groups
    Un getter nuevo
    O escribir tus normalizers, cuando quieras
    Ojo referencias circulares
    Pasar Extractor
    - ¿Serializar objetos encadenados?
    - ¿Deserializar objetos encadenados?

    View Slide

  136. COMPARANDO
    ¿Entonces cuál uso?

    View Slide

  137. Pues depende, los dos
    están muy bien

    View Slide

  138. Pues depende, los dos
    están muy bien

    View Slide

  139. Pues depende, los dos
    están muy bien

    View Slide

  140. Más que verlo como “cuál es
    mejor” hay que entender que
    son dos animales distintos
    https://www.flickr.com/photos/5of7/5531923725

    View Slide

  141. @vicqr
    Síntesis de críticas y puntos fuertes
    Licencia
    Mantenimiento
    Flexibilidad
    Curva aprendizaje
    Out-of-the-box
    XML
    JMSSERIALIZERBUNDLE SYMFONY SERIALIZER

    View Slide

  142. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    View Slide

  143. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?
    Sí Debería usar
    JMS

    View Slide

  144. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Debería usar
    JMS

    View Slide

  145. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS

    View Slide

  146. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Las transformaciones
    que quiero hacer son
    bastante comunes?
    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS

    View Slide

  147. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Las transformaciones
    que quiero hacer son
    bastante comunes?
    Sí Quizá sea más
    rápido usar JMS
    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS

    View Slide

  148. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Las transformaciones
    que quiero hacer son
    bastante comunes?
    Sí Quizá sea más
    rápido usar JMS
    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS
    No
    El componente
    Serializer me
    vendrá muy bien

    View Slide

  149. @vicqr
    ¿Y la performance?
    - Son parecidos
    - En el Symfony Serializer lo más lento es el ObjectNormalizer
    - Aunque se ha hecho más rápido y sigue siendo optimizado

    View Slide

  150. @vicqr
    ¿Y la performance?
    - Son parecidos
    - En el Symfony Serializer lo más lento es el ObjectNormalizer
    - Aunque se ha hecho más rápido y sigue siendo optimizado
    https://github.com/symfony/symfony/issues/16179
    Discusión y comparativas

    View Slide

  151. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Las transformaciones
    que quiero hacer son
    bastante comunes?
    Sí Quizá sea más
    rápido usar JMS
    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS
    No
    El componente
    Serializer me
    vendrá muy bien

    View Slide

  152. @vicqr
    Casos de uso
    ¿Quiero trabajar
    bastante con XML?

    No
    ¿Las transformaciones
    que quiero hacer son
    bastante comunes?
    Sí Quizá sea más
    rápido usar JMS
    No
    ¿Quiero “marranear” en
    el proceso de
    serialización?
    Sí Conviene que
    use JMS
    Debería usar
    JMS
    No
    El componente
    Serializer me
    vendrá muy bien
    ¿La performance
    importa mucho?
    Puedo usar el
    ObjectNormalizer
    Debería usar otro
    o hacerme el mío
    No Sí

    View Slide

  153. @vicqr
    Experiencia personal
    1. Hace años prefería JMSSerializer
    2. En algún momento encontré algo que no supe cómo hacer y cambié
    3. La primera impresión con SfSerializer fue que era costoso
    4. A día de hoy prefiero SfSerializer
    5. Si tengo que hacer algo rápido cojo JMSSerializer

    View Slide

  154. @vicqr
    Experiencia personal
    1. Hace años prefería JMSSerializer
    2. En algún momento encontré algo que no supe cómo hacer y cambié
    3. La primera impresión con SfSerializer fue que era costoso
    4. A día de hoy prefiero SfSerializer
    5. Si tengo que hacer algo rápido cojo JMSSerializer
    Por lo que he visto por ahí, es una evolución bastante común

    View Slide

  155. APUNTES FINALES
    Qué recordar

    View Slide

  156. @vicqr
    Qué recordar
    El serializador nos facilita crear distintas representaciones de los objetos
    Tanto el bundle como el componente son dos muy buenas herramientas
    Son DISTINTAS, están enfocadas diferente y son óptimas para distintos casos

    View Slide

  157. @vicqr
    Qué recordar
    El serializador nos facilita crear distintas representaciones de los objetos
    Tanto el bundle como el componente son dos muy buenas herramientas
    Son DISTINTAS, están enfocadas diferente y son óptimas para distintos casos
    El JMSSerializer te da más “hecho”
    El componente Serializer te facilita más montar lo que necesites

    View Slide

  158. @vicqr
    Resumen en un comentario de Github
    Just saying, but to me the Symfony's serializer does not especially suffer from a bad design,
    especially because its philosophy is far from the JMS serializer one. The idea of the Symfony's
    serializer is to keep things simple, not trying to answer every use-cases natively, but instead
    providing a great and simple architecture.
    Despite the fact it offers some great features, I'm almost never using the ObjectNormalizer
    and rather rely on custom normalizers (sometimes encoders) for each of my needs. Because
    when I'm writing code for my application, I know exactly what the output should be. I do not
    need something answering everything, just good and simple interfaces over it. This is way less
    brainfucking than a JMS Serializer, as soon as you're not trying to answer very generic needs.
    Now I can understand some of your concerns if you need to handle things in a very generic
    way, but to me there is nothing impossible with the current architecture regarding this.
    But anyway, I don't think the Symfony's serializer should try to replace entirely a JMS
    Serializer. Those are simply two different tools. Use or don't use them.
    https://github.com/symfony/symfony/issues/19330#issuecomment-233405451

    View Slide

  159. View Slide

  160. ¡Con el Serializer
    no puedo hacer
    XMLs decentes!

    View Slide

  161. ¡Con el Serializer
    no puedo hacer
    XMLs decentes!
    ¡El JMS es una
    basura!

    View Slide

  162. ¡Con el Serializer
    no puedo hacer
    XMLs decentes!
    ¡El JMS es una
    basura!
    ¡¿Para qué quieres
    normalizadores y
    encoders?!

    View Slide

  163. ¡Con el Serializer
    no puedo hacer
    XMLs decentes!
    ¡El JMS es una
    basura!
    ¡¿Para qué quieres
    normalizadores y
    encoders?!
    ¡Deshonras a tu
    familia utilizando
    ese código!

    View Slide

  164. Consultoría, formación y
    desarrollo
    @limenius
    @vicqr
    [email protected]
    ¡Gracias!
    Organizamos React Alicante
    28-30 Sep. 2017
    @ReactAlicante

    View Slide