Skip to content

Latest commit

 

History

History
312 lines (239 loc) · 10.5 KB

serializer.rst

File metadata and controls

312 lines (239 loc) · 10.5 KB

single: Serializer

How to Use the Serializer

Serializing and deserializing to and from objects and different formats (e.g. JSON or XML) is a very complex topic. Symfony comes with a Serializer Component </components/serializer>, which gives you some tools that you can leverage for your solution.

In fact, before you start, get familiar with the serializer, normalizers and encoders by reading the Serializer Component </components/serializer>.

Activating the Serializer

The serializer service is not available by default. To turn it on, activate it in your configuration:

# app/config/config.yml
framework:
    # ...
    serializer: { enable_annotations: true }
    # Alternatively, if you don't want to use annotations
    #serializer: { enabled: true }
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
    <framework:config>
        <!-- ... -->
<framework:serializer enable-annotations="true" />
<!--
Alternatively, if you don't want to use annotations
<framework:serializer enabled="true" />
-->
    </framework:config>
</container>
// app/config/config.php
$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'enable_annotations' => true,
        // Alternatively, if you don't want to use annotations
        //'enabled' => true,
    ),
));

Using the Serializer Service

Once enabled, the serializer service can be injected in any service where you need it or it can be used in a controller:

// src/AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Serializer\SerializerInterface;

class DefaultController extends Controller
{
    public function indexAction(SerializerInterface $serializer)
    {
        // keep reading for usage examples
    }
}

Adding Normalizers and Encoders

Once enabled, the serializer service will be available in the container and will be loaded with four encoders <component-serializer-encoders> (Symfony\\Component\\Serializer\\Encoder\\JsonEncoder, Symfony\\Component\\Serializer\\Encoder\\XmlEncoder, Symfony\\Component\\Serializer\\Encoder\\YamlEncoder, and Symfony\\Component\\Serializer\\Encoder\\CsvEncoder) and the ObjectNormalizer normalizer <component-serializer-normalizers>.

You can load normalizers and/or encoders by tagging them as serializer.normalizer <reference-dic-tags-serializer-normalizer> and serializer.encoder <reference-dic-tags-serializer-encoder>. It's also possible to set the priority of the tag in order to decide the matching order.

Here is an example on how to load the Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer:

# app/config/services.yml
services:
    get_set_method_normalizer:
        class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
        public: false
        tags: [serializer.normalizer]
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="get_set_method_normalizer" class="Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer" public="false">
            <tag name="serializer.normalizer" />
        </service>
    </services>
</container>
// app/config/services.php
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$container->register('get_set_method_normalizer', GetSetMethodNormalizer::class)
    ->setPublic(false)
    ->addTag('serializer.normalizer')
;

Using Serialization Groups Annotations

Enable serialization groups annotation <component-serializer-attributes-groups> with the following configuration:

# app/config/config.yml
framework:
    # ...
    serializer:
        enable_annotations: true
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <!-- ... -->
        <framework:serializer enable-annotations="true" />
    </framework:config>
</container>
// app/config/config.php
$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'enable_annotations' => true,
    ),
));

Next, add the @Groups annotations <component-serializer-attributes-groups-annotations> to your class and choose which groups to use when serializing:

$json = $serializer->serialize(
    $someObject,
    'json', array('groups' => array('group1'))
);

In addition to the @Groups annotation, the Serializer component also supports Yaml or XML files. These files are automatically loaded when being stored in one of the following locations:

  • The serialization.yml or serialization.xml file in the Resources/config/ directory of a bundle;
  • All *.yml and *.xml files in the Resources/config/serialization/ directory of a bundle.

Enabling the Metadata Cache

Metadata used by the Serializer component such as groups can be cached to enhance application performance. Any service implementing the Doctrine\Common\Cache\Cache interface can be used.

A service leveraging APCu (and APC for PHP < 5.5) is built-in.

# app/config/config_prod.yml
framework:
    # ...
    serializer:
        cache: serializer.mapping.cache.apc
<!-- app/config/config_prod.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <!-- ... -->
        <framework:serializer cache="serializer.mapping.cache.apc" />
    </framework:config>
</container>
// app/config/config_prod.php
$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'cache' => 'serializer.mapping.cache.apc',
    ),
));

Enabling a Name Converter

The use of a name converter <component-serializer-converting-property-names-when-serializing-and-deserializing> service can be defined in the configuration using the name_converter <reference-serializer-name_converter> option.

The built-in CamelCase to snake_case name converter <using-camelized-method-names-for-underscored-attributes> can be enabled by using the serializer.name_converter.camel_case_to_snake_case value:

# app/config/config.yml
framework:
    # ...
    serializer:
        name_converter: 'serializer.name_converter.camel_case_to_snake_case'
<!-- app/config/config.xml -->
<framework:config>
    <!-- ... -->
    <framework:serializer name-converter="serializer.name_converter.camel_case_to_snake_case" />
</framework:config>
// app/config/config.php
$container->loadFromExtension('framework', array(
    // ...
    'serializer' => array(
        'name_converter' => 'serializer.name_converter.camel_case_to_snake_case,
    ),
));

Going Further with the Serializer

ApiPlatform provides an API system supporting JSON-LD and Hydra Core Vocabulary hypermedia formats. It is built on top of the Symfony Framework and its Serializer component. It provides custom normalizers and a custom encoder, custom metadata and a caching system.

If you want to leverage the full power of the Symfony Serializer component, take a look at how this bundle works.

serializer/*