Mapping

Telling to serializer how it should transform your data is a very important step to assert that the transformation will not serialize the data with a wrong data type.

Zero User Mapping

TSantos Serializer will do its better to extract the must important metadata information from your class by reading its structure without the needing add custom annotations on every single property of your class. All you need to do is to write classes with good type-hint parameters and proper return types:

namespace App\Entity;

class Post
{
    private $id;
    private $title;
    private $comments;
    private $author;
    public function __construct(int $id) { ... } // mutator
    public function setTitle(string $title): { ... } // mutator
    public function addComment(Comment $comment) { ... } // mutator
    public function getAuthor(): Author { ... } // accessor
}

The serializer is smart enough to extract the data types from the property’s mutators and accessors and will (de-)serialize them respecting those types.

The previous example is a good start point because you don’t need to worry about the boring process of mapping all properties of all classes you want to serialize and is enough to cover the must use cases. However, you don’t have any control of what data should be serialized and when it should be serialized. That’s why you should use the mapping mechanism if you want a refined control over the serialization process.

The Serializer Builder

Before going ahead with mapping options, lets see how you should use the Serializer Builder to tell the serialize where are your mapping information:

$builder = new SerializerBuilder();

$serializer = $builder
  ->addMetadataDir('App\Document', '/project/config/serializer') // yaml metadata files
  ->addMetadataDir('App\Entity', '/project/src/Entity') // annotation metadata files
  ->build();

Note

Because the builder accepts many metadata directories, you can mix the supported mapping formats in the same serializer instance.

Note

You need to require the Symfony Yaml component to map your classes using the YAML format

$ composer require symfony/yaml

Note

You need to require the Doctrine Annotations component to map your classes using annotations syntax

$ composer require doctrine/annotations

and then enable the annotation reader in the Serializer Builder:

$serializer = $builder
  ->enableAnnotations()
  ->build();

Options Reference

BaseClass

Define what class the generated class should extends

/**
 * @BaseClass("My\Custom\Class")
 */
class Post {}
App\Entity\Post:
    baseClass: "My\Custom\Class"
<class name="App\Entity\Post" base-class="My\Custom\Class">

ExposeAs

The serialized name

/**
 * @ExposeAs("full_name")
 */
private $fullName;
properties:
    fullName:
        exposeAs: "full_name"
<property name="fullName" type="integer" expose-as="full_name" />

Getter

The accessor method to read the value

/**
 * @Getter("getMyCustomFullName")
 */
private $fullName;
properties:
    fullName:
        getter: "getMyCustomFullName"
<property name="fullName" getter="getMyCustomFullName" />

Tip

If you omit the getter option, the serializer will try to guess the getter automatically

Groups

The list of groups that the property can be serialized

/**
 * @Groups({"web","v1"})
 */
private $fullName;
properties:
    fullName:
        groups: ["web", "v1"]
<property name="fullName" groups="web,v1" />
<!-- or -->
<property name="fullName">
    <groups>
        <value>web</value>
        <value>v1</value>
    </groups>
</property>

Options

A key/value used by metadata configurators

/**
 * @Options({"format":"Y-m-d"})
 */
private $birthday;
properties:
    birthday:
        options: {"format":"Y-m-d"}
<property name="birthday">
    <options>
        <option name="format">Y-m-d</option>
    </options>
</property>

Tip

Metadata configurators can access the property’s options to modify its behavior.

Read Only

The property cannot be deserialized

/**
 * @ReadOnly
 */
private $id;
properties:
    id:
        readOnly: true
<property name="id" read-only="true">

Read Value Filter

A filter applied to the property value before encoding

/**
 * @ReadValueFilter("strtolower($value)")
 */
private $username;
properties:
    username:
        readValueFilter: "strtolower($value)"
<property name="username" read-value-filter="strtolower($value)" />

Tip

Metadata configurators can change the read-value-filter to customize the input/output of property’s values.

Setter

The mutator method to write the value

/**
 * @Setter("setMyCustomFullName")
 */
private $fullName;
properties:
    fullName:
        getter: "setMyCustomFullName"
<property name="fullName" getter="setMyCustomFullName" />

Tip

If you omit the setter option, the serializer will try to guess the setter automatically.

Type

The data type of mapped property

/**
 * @Type("integer")
 */
private $id;
properties:
    id:
        type: "integer"
<property name="id" type="integer" />

Tip

If you omit the type, the serializer will try to guess the type automatically.

Virtual Property

Mark a method as a virtual property. Its return will be encoded within the properties data.

/**
 * @VirtualProperty
 */
public function getAge(): int
{
    ...
}
virtualProperties:
    getAge: ~
<virtual-property name="getAge" />

Tip

If you omit the type option, the serializer will try to guess the type automatically thanks to metadata configurators.

Write Value Filter

A filter applied to the property value before writing it to objects

/**
 * @WriteValueFilter("\DateTime::createFromFormat('Y-m-d', $value)")
 */
private $birthday;
properties:
    birthday:
        writeValueFilter: "\DateTime::createFromFormat('Y-m-d', $value)"
<property name="username" write-value-filter="\DateTime::createFromFormat('Y-m-d', $value)" />

Tip

Metadata configurators can change the write-value-filter to customize the input/output of property’s values.

Performance

There is no difference in terms of performance between the mapping formats. In fact, the metadata generated by the mapping will be cached and reused in the next serialization operation, so you can choose the most comfortable format for you.