From 61b9c530e78840bb86e206cfc9e2ba3a3badd9bb Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Mon, 8 Jan 2018 14:40:15 +0000 Subject: [PATCH 1/2] Add documentation about the (de)serialization of interfaces and abstract classes --- components/serializer.rst | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/components/serializer.rst b/components/serializer.rst index 9584b10f450..5fdfc535334 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -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 + + + + + + + + + + + + Learn more ---------- From ac831b081ae838acd2bb86befcfa02f5756a934f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 8 Jan 2018 17:57:37 +0100 Subject: [PATCH 2/2] Minor fixes and some tweaks --- components/serializer.rst | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index 5fdfc535334..b3bfed16e14 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -981,26 +981,32 @@ 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 +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". +When dealing with objects that are fairly similar or share properties, you may +use interfaces 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. +The discriminator is the field (in the serialized string) used to differentiate +between the possible objects. In practice, when using the Serializer component, +pass the :class:`Symfony\\Component\\Serializer\\Mapping\\ClassDiscriminatorResolver` +to the :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`. -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:: +Consider an application that defines an abstract ``CodeRepository`` class +extended by ``GitHubCodeRepository`` and ``BitBucketCodeRepository`` classes. +This example shows how to serialize and deserialize those objects:: - $discriminatorResolver = new ClassDiscriminatorResolver(); - $discriminatorResolver->addClassMapping(CodeRepository::class, new ClassDiscriminatorMapping('type', [ + $discriminator = new ClassDiscriminatorResolver(); + $discriminator->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())); + $serializer = new Serializer( + array(new ObjectNormalizer(null, null, null, null, $discriminator)), + array('json' => new JsonEncoder()) + ); $serialized = $serializer->serialize(new GitHubCodeRepository()); // {"type": "github"} @@ -1008,8 +1014,9 @@ like in the following example:: $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: +If the class metadata factory is enabled as explained in the +:ref:`Attributes Groups section `, you +can use this simpler configuration: .. configuration-block:: @@ -1055,7 +1062,6 @@ simply use the following configuration: - Learn more ----------