In Symfony 2.7, the Symfony Serializer component has been greatly improved with lots of new features. This article introduces the most important ones.

Support for serialization groups in XML and YAML files

Contributed by
Kévin Dunglas
in #12092.

A few months ago we already talked about defining serialization groups via annotations. Before using them, you only have to enabled them with the enable_annotations configuration option:

1
2
3
4
# app/config/services.yml
framework:
    # ...
    serializer: { enable_annotations: true }

For those of you who don't like annotations, you can now define serialization groups via XML or YAML files. The Serializer component will look for serialization.xml or serialization.yml files located in the Resources/config/ directory of your bundles. In addition, it will look for any XML or YAML file located inside the Resources/config/serialization/ directory.

Regardless of the configuration format used, the metadata generated by these serialization groups can be cached using Doctrine Cache. This will provide a great performance improvement in your application. For example, if your server provides support for APC or APCu, enable the serializer cache with the following configuration:

1
2
3
4
# app/config/config.yml
framework:
    serializer:
        cache: serializer.mapping.cache.apc

New ObjectNormalizer

Contributed by
Kévin Dunglas
in #13257.

In Symfony 2.6 there were two types of normalizers: GetSetMethodNormalizer and PropertyNormalizer. Symfony 2.7 introduces a new normalizer called ObjectNormalizer. The main advantage over the basic GetSetMethodNormalizer is that it supports protected and private properties and even properties that only define getter/isser methods:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class MyObject
{
    public $foo = 'foo';

    public getBar()
    {
       return 'bar';
    }

    public isBaz()
    {
        return true;
    }
}

use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

$normalizer = new ObjectNormalizer();
$result = $normalizer->normalize(new MyObject());
// $result = ['foo' => 'foo', 'bar' => 'bar', 'baz' => true]

To simplify setting up things, this new normalizer, as well as the serialization groups, are enabled by default in the FrameworkBundle.

Ability to change property names

Contributed by
Kévin Dunglas
in #13120.

The GetSetMethodNormalizer provides a basic mechanism to tweak the conversion of the property name into the getter/setter method name:

1
2
3
4
5
// ...
$normalizer = new GetSetMethodNormalizer();
$normalizer->setCamelizedAttributes(array('first_name'));

$serializer = new Serializer(array($normalizer), array($encoder));

This code allows the first_name property to be correctly converted into the getFirstName() method instead of the wrong getFirst_name() method.

In 2.7 the setCamelizedAttributes() method has been deprecated in favor of a new NameConverter generic converter. The first available name converter turns camel case into snake case and the other way around:

1
2
3
4
5
6
7
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

// ...
$nameConverter = new CamelCaseToSnakeCaseNameConverter(array('first_name'));
$normalizer = new GetSetMethodNormalizer(null, $nameConverter);
$serializer = new Serializer(array($normalizer), array($encoder));

Deserialize into an existing object

Contributed by
Kévin Dunglas
in #13252.

It's common to create new objects whenever you deserialize information. However, in Symfony 2.7 you can deserialize into an existing object. This can be useful for instance to update an object retrieved through Doctrine ORM:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$existingProduct = $this->getDoctrine()->...

$product = $this->normalizer->denormalize(
    array('bar' => 'bar'),
    'AppBundle\\Entity\\Product',
    null,
    array('object_to_populate' => $existingProduct)
);

// $product and $existingProduct are references to the same object

DunglasJsonLdApiBundle

In order to better showcase the new features of the Serializer component, Kévin has developed a new bundle called DunglasJsonLdApiBundle. This bundle allows to create hypermedia APIs with JSON-LD and Hydra support on top of the Serializer component.