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

Mastering the Symfony Serializer

Mastering the Symfony Serializer

The Symfony Serializer Component exists since the very beginning of Symfony 2. Years after years, it gained a lot of new features useful to transform various data formats to PHP structures and the opposite. It is also a foundation block of API Platform and a first-class citizen in FOSRest.

Let's dive into this component. We will cover the basic concepts behind the serialization process: normalization, denormalization, encoding and decoding.

Then we will discover all the little known features of the component: JSON, XML and CSV support, file handling with "data:" URIs, serialization groups, attributes names conversion, trees support, updating existing objects, dealing with circular references.

Finally we will learn how to create custom normalizers and encoders; and how to modify the behavior of the builtin ones using composition.

Avatar for Kévin Dunglas

Kévin Dunglas

May 17, 2018
Tweet

More Decks by Kévin Dunglas

Other Decks in Technology

Transcript

  1. @dunglas - Les-Tilleuls.coop Kévin Dunglas ❏ Co-founder of Les-Tilleuls.coop ❏

    Symfony Core Team (Serializer, PropertyInfo, WebLink, autowiring, PSR-7 Bridge…) ❏ Creator of API Platform 2 @dunglas
  2. @dunglas - Les-Tilleuls.coop Dev, consulting and training (Masterclass) Self-managed since

    2011 ⬆ 97% in 2016, 25 people sharing benefits ➡ [email protected] Les-Tilleuls.coop 3
  3. @dunglas - Les-Tilleuls.coop The Serializer component is meant to be

    used to turn objects into a specific format (XML, JSON, YAML, ...) and the other way around. 5 “ ”
  4. @dunglas - Les-Tilleuls.coop Most popular use case: retrieve/send data from/to

    external systems ❏ Create web APIs ❏ Hydrate objects from DB results or external API responses ❏ Exchange data between apps (or [micro]services) 6
  5. @dunglas - Les-Tilleuls.coop They Use the Serializer Component 7 New

    in Symfony 4.1: the Messenger component also uses the Serializer
  6. @dunglas - Les-Tilleuls.coop ChainNormalizer and ChainEncoder ❏ A list of

    normalizers and encoders are passed to the Serializer’s constructor ❏ The 1st implementation having a supports* method returning true is used ❏ Extension point to register custom implems for specific classes or formats 11
  7. @dunglas - Les-Tilleuls.coop Why Not PHP’s (un)?serialize? Super fast, and

    preserve types, but… ❏ Not interoperable ❏ Not secure for non-internal use ↓ 19
  8. @dunglas - Les-Tilleuls.coop Why Not json_(en|de)code? ❏ Cannot hydrate non-anonymous

    objects when decoding ❏ Limited feature set (groups, circular references, trees…) Symfony Serializer’s JSON encoder uses json_encode/json_decode internally. 22
  9. @dunglas - Les-Tilleuls.coop Native Object Normalizers 43 Access Data Supports

    Dependencies PropertyNormalizer Public properties - GetSetMethodNormalizer get / set, is / has - ObjectNormalizer Public properties get / set, is / has add / remove __call (opt-in) __get (opt-in) symfony/property-access optional, but boosts perf: symfony/cache ObjectNormalizer is the smartest generic normalizer. It is enabled by default when using Symfony full stack.
  10. @dunglas - Les-Tilleuls.coop An Object Mixing Public Props and Accessors

    Unfortunately neither PropertyNormalizer nor GetSetMethodNormalizer can deal with this object. ObjectNormalizer can! 46
  11. @dunglas - Les-Tilleuls.coop Normalizers for Special Objects 49 Supported Objects

    Dependency DataUriNormalizer File <-> data: URI \SplFileInfo \SplFileObject HttpFoundation’s File optional, to guess MIME types: symfony/ http-foundation DateIntervalNormalizer Date interval <-> ISO 8601 string \DateInterval - DateTimeNormalizer Date & time <-> ISO 8601 string \DateTimeInterface - Since 4.1 ConstraintViolationListNormalizer Validation errors -> RFC 7807 (API Problem Details) Validator’s ConstraintViolationListInterface symfony/validator JsonSerializableNormalizer Json_encode’s like JsonSerializable \JsonSerializable - They are all available by default when using the Symfony full stack framework.
  12. @dunglas - Les-Tilleuls.coop Recursive Normalization: Thanks to the Chain of

    Responsibility ❏ Generic object normalizers implement the SerializerAwareInterface ❏ They recursively call Serializer::normalize() for all values they normalize 52
  13. @dunglas - Les-Tilleuls.coop Recursive Normalization: Thanks to the Chain of

    Responsibility In our previous example: ❏ Conference is normalized by ObjectNormalizer ❏ Because supportsNormalization() method of normalizers registered before it return false ❏ DateTime by DateTimeNormalizer ❏ SplFileObject by DataUriNormalizer 53
  14. @dunglas - Les-Tilleuls.coop Built-In Encoders and Decoders 55 Format Dependencies

    JsonEncoder JSON - XmlEncoder XML - CsvEncoder CSV - YamlEncoder YAML symfony/yaml They are all available by default when using the Symfony full stack framework.
  15. @dunglas - Les-Tilleuls.coop Recursive Denormalization Recursive normalization works out of

    the box (thanks to the SerializerAwareInterface). Unfortunately, this is not the case for denormalization: 72
  16. @dunglas - Les-Tilleuls.coop Recursive Denormalization The Serializer cannot guess that:

    ❏ date must be denormalized as a \DateTime (and not a string) ❏ logo as a \SplFileObject (and not a string) 73
  17. @dunglas - Les-Tilleuls.coop PropertyInfo: Type Metadata Sources 75 Dependencies Getter

    / Setter / Adder / Remover / Constructor - PHPDoc phpdocumentator/reflection-docblock Doctrine ORM mappings symfony/doctrine-bridge Optional but boosts perf: symfony/cache
  18. @dunglas - Les-Tilleuls.coop Type Safety Bonus: If a PropertyInfo Type

    extractor is registered, the built-in object normalizers will also ensure that the type of the data to deserialize matches the intended one! 80
  19. @dunglas - Les-Tilleuls.coop Type Safety 81 This behavior can be

    disabled with the ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT context key.
  20. @dunglas - Les-Tilleuls.coop Registration and Usage 100 ❏ Conference instances

    will be normalized by the ConferenceNormalizer ❏ All other objects by the PropertyNormalizer ❏ Order matters!
  21. @dunglas - Les-Tilleuls.coop Typehint SerializerInterface anywhere, A fully featured Serializer

    is injected: ❏ All built-in normalizers and encoders ❏ PropertyInfo and PropertyAccess related features ❏ MetadataLoader with annotation, XML and YAML support 102
  22. @dunglas - Les-Tilleuls.coop Also New in Symfony 4.1 ❏ Support

    for abstract classes (DiscriminatorMap) ❏ Massive performance improvements (+30%) ❏ Bunch of new options for the XML and CSV encoders 104
  23. @dunglas - Les-Tilleuls.coop A True Alternative: jms/serializer 105 Symfony JMS

    Pattern normalizer + encoder Chain of responsibility Visitor License MIT: permissive, compatible with most other (F)OSS licenses Apache v2: permissive, but incompatible with GPLv2 (Drupal, Wordpress, Joomla) V2 will be MIT: schmittjoh/serializer#950 Formats Core: JSON, XML, YAML, CSV, data: URI, RFC7807, ISO8601 API Platform: JSON-LD, HAL, Swagger, Hydra JSON, XML Maintainers SF Core Team (15 people) 2 people (1 active) Release process Semver, guaranteed upgrade path, time based release, strong BC policy Semver