Skip to main content

Symfony Doctrine JMS Serializer Max Depth

There is a great MaxDepth exclusion policy in JMS Serializer however there is also a big  mystery how it works.

Lets think of normal case where you are from the start excluding everything in your model and then exposing the fields separately.

We have entity called Product which has properties id, category and price. From these category and price are exposed.

Now we know or guess that category probably has a lot of connections to many places and we’re not sure about it’s exclusion policies and we’d like to limit the depth of our object to only one level. Meaning we don’t want to expose nothing from category entity which is a entity reference.

namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
 * @ORM\Entity
 * @ORM\Table(name="products")
 * @Serializer\ExclusionPolicy("all")
class Product
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue
    private $id;
     * @var \ProductCategory
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
     * @ORM\JoinColumns({
     *     @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=false)
     * })
     * @Serializer\Expose()
     * @Serializer\MaxDepth(1)
    private $category;
     * @var decimal
     * @Assert\NotNull()
     * @ORM\Column(name="price", type="decimal", precision=10, scale=2, nullable=false)
     * @Serializer\Expose()
    private $price;

So as you can see from the example we have placed

* @Serializer\Expose()
* @Serializer\MaxDepth(1)

MaxDepth(1) to our category property.

Now to make this all work, in our controller we have to give the serializer a custom parameter to let it know that we are using these MaxDepth annotations.

If you are using FOS\RestBundle:

* @Rest\View(serializerEnableMaxDepthChecks=true)

If you are not then try this:

use JMS\Serializer\SerializationContext; $serializer->serialize($data, 'json', SerializationContext::create()->enableMaxDepthChecks());