Search code examples
jsonsymfonyfosrestbundle

Return a json-encoded, non-recursive object in FOSRestBundle


I am building a REST API with FOSRestBundle. My entities have quite a bit of OneToMany/ManyToOne bidirectional relationships. Whenever I want to GET some entity with the JSON format, e.g. web/app_dev.php/users/1.json I'm getting a much bigger object than I actually need: all related objects are recursively included. My controllers return the object and have the @View annotations.

How can I return an object that just reflects the database row (i.e. with only the ids of me related objects)?


Solution

  • You can play with annotation (http://jmsyst.com/libs/serializer/master/reference/annotations : see Groups, Expose/Exclude, or MaxDepth)

    I prefer to use the Groups annotation (i have exactly what i want !)

    For example :

    In the Entity class :

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @JMS\Groups({"main"})
     */
    private $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="DocumentUnique", inversedBy="Evaluations")
     * @ORM\JoinColumn(name="documentUniqueId", referencedColumnName="id")
     * @JMS\Groups({"show", "all"}) 
     */
    protected $DocumentUnique;    
    
    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=20)
     * @JMS\Groups({"main","all"}) 
     */
     private $title;
    

    In the Controller :

    /**
     * @Rest\View(serializerGroups={"main"})
     */    
    public function cgetAction()
    {
        return $this->getRepository('MyEntity')->findAll();
    }
    

    In you want to expose the id of one relation, you can use the VirtualProperty annotation :

    /**
     * @JMS\VirtualProperty
     * @JMS\SerializedName("documentUniqueId")
     * @JMS\Groups("main") 
     */    
    public function getDocumentUniqueId() {
        if (!$this->DocumentUnique) return null;
        return $this->DocumentUnique->getId();
    }