Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add documentation about the (de)serialization of interfaces and abstr…
…act classes
  • Loading branch information
sroze committed Jan 8, 2018
commit 61b9c530e78840bb86e206cfc9e2ba3a3badd9bb
75 changes: 75 additions & 0 deletions components/serializer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,81 @@ will be thrown. The type enforcement of the properties can be disabled by settin
the serializer context option ``ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT``
to ``true``.

Serializing interfaces and abstract classes
-------------------------------------------

When dealing with objects that are fairly similar or share properties, you'd usually use
intefaces or abstract classes. The Serializer component allows you to serialize and deserialize
these objects using a "discrimator class mapping".

The discrimator is the field (in the serialized string) you are going to use to differentiate the
different objects.

When using the Serializer component, you need to give the :class:`Symfony\\Component\\Serializer\\Mapping\\ClassDiscriminatorResolver` to the :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`,
like in the following example::

$discriminatorResolver = new ClassDiscriminatorResolver();
$discriminatorResolver->addClassMapping(CodeRepository::class, new ClassDiscriminatorMapping('type', [
'github' => GitHubCodeRepository::class,
'bitbucket' => BitBucketCodeRepository::class,
]));

$serializer = new Serializer(array(new ObjectNormalizer(null, null, null, null, $discriminatorResolver)), array('json' => new JsonEncoder()));

$serialized = $serializer->serialize(new GitHubCodeRepository());
// {"type": "github"}

$repository = $serializer->unserialize($serialized, CodeRepository::class, 'json');
// instanceof GitHubCodeRepository

If you have enabled the class metadata factory as described in [Attributes Groups](#attributes-groups), you can
simply use the following configuration:

.. configuration-block::

.. code-block:: php-annotations

namespace App;

use Symfony\Component\Serializer\Annotation\DiscriminatorMap;

/**
* @DiscriminatorMap(typeProperty="type", mapping={
* "github"="App\GitHubCodeRepository",
* "bitbucket"="App\BitBucketCodeRepository"
* })
*/
interface CodeRepository
{
// ...
}

.. code-block:: yaml

App\CodeRepository:
discriminator_map:
type_property: type
mapping:
github: 'App\GitHubCodeRepository'
bitbucket: 'App\BitBucketCodeRepository'

.. code-block:: xml

<?xml version="1.0" ?>
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
http://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
>
<class name="App\CodeRepository">
<discriminator-map type-property="type">
<mapping type="github" class="App\GitHubCodeRepository" />
<mapping type="bitbucket" class="App\BitBucketCodeRepository" />
</discriminator-map>
</class>
</serializer>


Learn more
----------

Expand Down