JMS Serializer: How to limit the depth of serialisation for an object graph
Solution 1
Because I did not have access to the latest version of the serializer I had to find a workaround to the @MaxDepth. This may also help you.
Use @JMS\ExclusionPolicy("all") on all entities that are connected.
Now use @JMS\Expose only on those properties that you want to have serialize. On join relations only use this annotation in one direction. That will fix your problem.
namespace FinalConcept\TimeTracker\EntitiesBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* FinalConcept\TimeTracker\EntitiesBundle\Entity
*
* @JMS\ExclusionPolicy("all")
* @ORM\Table(name="users")
* @ORM\Entity(repositoryClass="FinalConcept\TimeTracker\EntitiesBundle\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @JMS\Expose
* @ORM\ManyToOne(targetEntity="company", inversedBy="users")
* @ORM\JoinColumn(name="company_id", referencedColumnName="id")
*/
private $company;
}
Solution 2
As of the latest version, using @MaxDepth() annotation and SerializationContext::create()->enableMaxDepthChecks() in the controller does the job.
concept
Updated on July 10, 2022Comments
-
concept almost 2 years
Maybe it is just my misunderstanding of this annotation however it does not seam to work as expected.
I have the following object graph
User -> Company -> Users -> Groups -> Permissions
As you can see there will be some recursion. JMS handles this quite well by not serialising the other user's company properties as well as not the current user.
However I want the serialization to stop at and include company.
I have tried this expecting that once the level $context->level = 2 it would stop
<?php namespace FinalConcept\TimeTracker\EntitiesBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use JMS\Serializer\Annotation as JMS; /** * FinalConcept\TimeTracker\EntitiesBundle\Entity * * @ORM\Table(name="users") * @ORM\Entity(repositoryClass="FinalConcept\TimeTracker\EntitiesBundle\Repository\UserRepository") */ class User implements UserInterface, \Serializable { /** * @ORM\ManyToOne(targetEntity="company", inversedBy="users") * @ORM\JoinColumn(name="company_id", referencedColumnName="id") * @JMS\MaxDepth(depth=1) */ private $company; }
However this is not the case. Even stepping through the code has not shed any light on how to stop this.
I am happy to create a custom handler if I can only invoke it for a specific path i.e. User.Company
I also need this for User.Groups which has the following graph
User -> Groups -> Permissions -> Users -> Groups -> users ....
Thanks in advance for any help how to limit the depth of serialization for an object graph
-
famas23 almost 6 yearsHey thank you for your amazing response. is it possible to mention
@MaxDepth
on the hole class?? -
Alexandru Cosoi almost 6 yearsNo sry. @MaxDepth is marked as property/Method annontation @Target({"PROPERTY","METHOD"})