Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize slice of ArrayCollection using JMS Serializer?

I want to serialize into JSON entity Category with collection of Presentation entities (see below) to use for REST API.

The endpoint will look something like this /api/v1/categories/1

When dataset is small and when Category only has only 5-10 related Presentations then the resulting response is not too large. However when Category starts to have let's say 100 or 200 related Presentations then obviously I do not want to return all of them, but would like to "paginate" the results, eg. when calling endpoint:

/api/v1/categories/1?page=2 - would return only "2nd page"

/api/v1/categories/1/page=3 - would return "3rd page"

or even it can be with offset and limit:

/api/v1/categories/1?offset=20&limit=10

but the problem is: how to make JMS serializer serialize only a slice of the collection?

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
 */
class Category
{

    /**
     * @var string
     * @ORM\Column(type="string")
     * @JMS\Expose()
     * @JMS\Groups({"get-category"})
     */
    private $title;


    // ...

    /**
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Presentation", mappedBy="categories", fetch="EXTRA_LAZY")
     * @JMS\Groups({"get-category"})
     * @JMS\Expose()
     */
    private $presentations;


    // ...

}

ps. I know that for example if I want to get always first 5 elements of the collection, I can add created @VirtualProperty and slice the doctrine ArrayCollection as shown below. But the problem here is that I cannot pass the offset parameters to this method. As it would be called internally by JMSSerializer somewhere...

/**
 * @JMS\VirtualProperty()
 *
 */
public function getFirstFivePresentations(){
    return $this->presentations->slice(0,5);
}
like image 522
Dimitry K Avatar asked Feb 02 '26 09:02

Dimitry K


1 Answers

You are trying to implement the incorrect approach in your REST API. Each entity must have it's own path.

The right way is to have two different endpoints:

/api/v1/categories/1 -> Serialized category with no presentations

/api/v1/categories/1/presentations -> Serialized collection of presentaions

And here you should use pagination

/api/v1/categories/1/presentations?offset=20&limit=10

like image 105
Jekis Avatar answered Feb 03 '26 23:02

Jekis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!