123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- Exclusion Strategies
- ====================
- Introduction
- ------------
- The serializer supports different exclusion strategies. Each strategy allows
- you to define which properties of your objects should be serialized.
- General Exclusion Strategies
- ----------------------------
- If you would like to always expose, or exclude certain properties. Then, you can
- do this with the annotations ``@ExclusionPolicy``, ``@Exclude``, and ``@Expose``.
- The default exclusion policy is to exclude nothing. That is, all properties of the
- object will be serialized. If you only want to expose a few of the properties,
- then it is easier to change the exclusion policy, and only mark these few properties:
- .. code-block :: php
- <?php
- use JMS\Serializer\Annotation\ExclusionPolicy;
- use JMS\Serializer\Annotation\Expose;
- /**
- * The following annotations tells the serializer to skip all properties which
- * have not marked with @Expose.
- *
- * @ExclusionPolicy("all")
- */
- class MyObject
- {
- private $foo;
- private $bar;
- /**
- * @Expose
- */
- private $name;
- }
- .. note ::
- A property that is excluded by ``@Exclude`` cannot be exposed anymore by any
- of the following strategies, but is always hidden.
- Versioning Objects
- ------------------
- JMSSerializerBundle comes by default with a very neat feature which allows
- you to add versioning support to your objects, e.g. if you want to
- expose them via an API that is consumed by a third-party:
- .. code-block :: php
- <?php
- class VersionedObject
- {
- /**
- * @Until("1.0.x")
- */
- private $name;
- /**
- * @Since("1.1")
- * @SerializedName("name")
- */
- private $name2;
- }
- .. note ::
- ``@Until``, and ``@Since`` both accept a standardized PHP version number.
- If you have annotated your objects like above, you can serializing different
- versions like this::
- use JMS\Serializer\SerializationContext;
- $serializer->serialize(new VersionObject(), 'json', SerializationContext::create()->setVersion(1));
- Creating Different Views of Your Objects
- ----------------------------------------
- Another default exclusion strategy is to create different views of your objects.
- Let's say you would like to serialize your object in a different view depending
- whether it is displayed in a list view or in a details view.
- You can achieve that by using the ``@Groups`` annotation on your properties. Any
- property without an explicit ``@Groups`` annotation will be included in a
- ``Default`` group, which can be used when specifying groups in the serialization
- context.
- .. code-block :: php
- use JMS\Serializer\Annotation\Groups;
- class BlogPost
- {
- /** @Groups({"list", "details"}) */
- private $id;
- /** @Groups({"list", "details"}) */
- private $title;
- /** @Groups({"list"}) */
- private $nbComments;
- /** @Groups({"details"}) */
- private $comments;
- private $createdAt;
- }
- You can then tell the serializer which groups to serialize in your controller::
- use JMS\Serializer\SerializationContext;
- $serializer->serialize(new BlogPost(), 'json', SerializationContext::create()->setGroups(array('list')));
- //will output $id, $title and $nbComments.
- $serializer->serialize(new BlogPost(), 'json', SerializationContext::create()->setGroups(array('Default', 'list')));
- //will output $id, $title, $nbComments and $createdAt.
- Overriding Groups of Deeper Branches of the Graph
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- In some cases you want to control more precisely what is serialized because you may have the same class at different
- depths of the object graph.
- For example if you have a User that has a manager and friends::
- use JMS\Serializer\Annotation\Groups;
- class User
- {
- private $name;
- /** @Groups({"manager_group"}) */
- private $manager;
- /** @Groups({"friends_group"}) */
- private $friends;
- public function __construct($name, User $manager = null, array $friends = null)
- {
- $this->name = $name;
- $this->manager = $manager;
- $this->friends = $friends;
- }
- }
- And the following object graph::
- $john = new User(
- 'John',
- new User(
- 'John Manager',
- new User('The boss'),
- array(
- new User('John Manager friend 1'),
- )
- ),
- array(
- new User(
- 'John friend 1',
- new User('John friend 1 manager')
- ),
- new User(
- 'John friend 2',
- new User('John friend 2 manager')
- ),
- )
- );
- You can override groups on specific paths::
- use JMS\Serializer\SerializationContext;
- $context = SerializationContext::create()->setGroups(array(
- 'Default', // Serialize John's name
- 'manager_group', // Serialize John's manager
- 'friends_group', // Serialize John's friends
- 'manager' => array( // Override the groups for the manager of John
- 'Default', // Serialize John manager's name
- 'friends_group', // Serialize John manager's friends. If you do not override the groups for the friends, it will default to Default.
- ),
- 'friends' => array( // Override the groups for the friends of John
- 'manager_group' // Serialize John friends' managers.
- 'manager' => array( // Override the groups for the John friends' manager
- 'Default', // This would be the default if you did not override the groups of the manager property.
- ),
- ),
- ));
- $serializer->serialize($john, 'json', $context);
- This would result in the following json::
- {
- "name": "John",
- "manager": {
- "name": "John Manager",
- "friends": [
- {
- "name": "John Manager friend 1"
- }
- ]
- },
- "friends": [
- {
- "manager": {
- "name": "John friend 1 manager"
- },
- },
- {
- "manager": {
- "name": "John friend 2 manager"
- },
- },
- ]
- }
- Limiting serialization depth of some properties
- -----------------------------------------------
- You can limit the depth of what will be serialized in a property with the
- ``@MaxDepth`` annotation.
- This exclusion strategy is a bit different from the others, because it will
- affect the serialized content of others classes than the one you apply the
- annotation to.
- .. code-block :: php
- use JMS\Serializer\Annotation\MaxDepth;
- class User
- {
- private $username;
- /** @MaxDepth(1) */
- private $friends;
- /** @MaxDepth(2) */
- private $posts;
- }
- class Post
- {
- private $title;
- private $author;
- }
- In this example, serializing a user, because the max depth of the ``$friends``
- property is 1, the user friends would be serialized, but not their friends;
- and because the the max depth of the ``$posts`` property is 2, the posts would
- be serialized, and their author would also be serialized.
- You need to tell the serializer to take into account MaxDepth checks::
- use JMS\Serializer\SerializationContext;
- $serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks());
- Dynamic exclusion strategy
- --------------------------
- If the previous exclusion strategies are not enough, is possible to use the ``ExpressionLanguageExclusionStrategy``
- that uses the `symfony expression language`_ to
- allow a more sophisticated exclusion strategies using ``@Exclude(if="expression")`` and ``@Expose(if="expression")`` methods.
- .. code-block :: php
- <?php
- class MyObject
- {
- /**
- * @Exclude(if="true")
- */
- private $name;
- /**
- * @Expose(if="true")
- */
- private $name2;
- }
- .. note ::
- ``true`` is just a generic expression, you can use any expression allowed by the Symfony Expression Language
- To enable this feature you have to set the Expression Evaluator when initializing the serializer.
- .. code-block :: php
- <?php
- use JMS\Serializer\Expression\ExpressionEvaluator;
- use JMS\Serializer\Expression\SerializerBuilder;
- use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
-
- $serializer = SerializerBuilder::create()
- ->setExpressionEvaluator(new ExpressionEvaluator(new ExpressionLanguage()))
- ->build();
- .. _symfony expression language: https://github.com/symfony/expression-language
|