Answer the question
In order to leave comments, you need to log in
How to properly serialize a collection of elements with pagination data?
There is Symfony 5, you need to create a couple of endpoints that return a list of elements with pagination.
I decided to use FosRestBundle + babdev/pagerfanta-bundle , because half of the API Platform documentation is incomprehensible and difficult to adapt to myself without rewriting a third of the project.
I decided to make pagination following the example of the SymfonyCasts lesson (adapted to the modern version).
Source:
<?php
namespace AppBundle\Pagination;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
class PaginationFactory
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function createCollection(QueryBuilder $qb, Request $request, $route, array $routeParams = array())
{
$page = $request->query->get('page', 1);
$adapter = new DoctrineORMAdapter($qb);
$pagerfanta = new Pagerfanta($adapter);
$pagerfanta->setMaxPerPage(10);
$pagerfanta->setCurrentPage($page);
$programmers = [];
foreach ($pagerfanta->getCurrentPageResults() as $result) {
$programmers[] = $result;
}
$paginatedCollection = new PaginatedCollection($programmers, $pagerfanta->getNbResults());
$createLinkUrl = function($targetPage) use ($route, $routeParams) {
return $this->router->generate($route, array_merge(
$routeParams,
array('page' => $targetPage)
));
};
$paginatedCollection->addLink('self', $createLinkUrl($page));
$paginatedCollection->addLink('first', $createLinkUrl(1));
$paginatedCollection->addLink('last', $createLinkUrl($pagerfanta->getNbPages()));
if ($pagerfanta->hasNextPage()) {
$paginatedCollection->addLink('next', $createLinkUrl($pagerfanta->getNextPage()));
}
if ($pagerfanta->hasPreviousPage()) {
$paginatedCollection->addLink('prev', $createLinkUrl($pagerfanta->getPreviousPage()));
}
return $paginatedCollection;
}
}
public function listAction(Request $request)
{
$qb = $this->getDoctrine()
->getRepository('AppBundle:Programmer')
->findAllQueryBuilder();
$paginatedCollection = $this->get('pagination_factory')
->createCollection($qb, $request, 'api_programmers_collection');
$response = $this->createApiResponse($paginatedCollection, 200);
return $response;
}
Answer the question
In order to leave comments, you need to log in
It was necessary to implement JsonSerializable in the PaginatedCollection class in order for the serializer to start working with this class
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question