O que é uma Lista em Symfony?
Uma lista em Symfony se refere a uma página que lista vários itens relacionados a um modelo de dados específico. É comum um controller de lista retornar uma resposta em JSON para ser utilizada em uma API REST, por exemplo. O FOSRESTBundle é uma ferramenta popular para implementar APIs RESTful em projetos Symfony.
Como criar um controller de Lista com FOSRESTBundle em Symfony?
Para criar um controller de lista utilizando o FOSRESTBundle, primeiro é necessário definir a rota para a ação do controller. Isso pode ser feito utilizando a função get
no arquivo routing.yml
:
api_movies_list:
path: /api/movies
methods: GET
defaults: { _controller: AppBundle:Movie:list }
Nesse exemplo, a rota /api/movies
será associada à ação list
do controller AppBundle:Movie
.
Em seguida, é preciso criar a ação list
no controller MovieController
:
namespace AppBundleController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use FOSRestBundleControllerFOSRestController;
class MovieController extends FOSRestController
{
public function listAction(Request $request)
{
$entityManager = $this->getDoctrine()->getManager();
$movies = $entityManager->getRepository('AppBundle:Movie')->findAll();
$view = $this->view($movies, 200);
return $this->handleView($view);
}
}
Nesse exemplo, a ação list
retorna todos os filmes cadastrados no banco de dados, utilizando o entityManager
do Doctrine. Em seguida, a resposta é criada com o método $this->view()
do FOSRestBundle e enviada com o método $this->handleView()
.
Como personalizar a resposta da Lista em Symfony?
O FOSRESTBundle permite personalizar a resposta de uma lista através de vários formatos, como JSON, XML, YAML e HTML. Para personalizar a resposta em JSON, por exemplo, é possível utilizar o método $this->view()
com parâmetros adicionais:
$view = $this->view($movies, 200);
$view->setContext($view->getContext()->setGroups(array('list')));
return $this->handleView($view);
Nesse exemplo, a propriedade groups
é setada para o valor list
, para incluir apenas os campos necessários na resposta. É possível definir grupos personalizados no arquivo config.yml
, como no exemplo a seguir:
fos_rest:
serializer:
groups:
- list
- details
- admin
Dessa forma, o FOSRESTBundle utiliza o grupo list
para personalizar a resposta do controller de lista.
Como utilizar o filtro de Busca em uma Lista em Symfony?
É comum uma lista em Symfony possuir filtros de busca para facilitar a navegação dos usuários. O FOSRESTBundle oferece uma solução simples para isso, utilizando a biblioteca Elastica
para buscar os dados no banco de dados.
Para utilizar o filtro de busca, é preciso adicionar uma rota para a ação de busca e personalizar a resposta do controller para incluir o resultado da busca:
api_movies_search:
path: /api/movies/search
methods: GET
defaults: { _controller: AppBundle:Movie:search }
public function searchAction(Request $request)
{
$searchTerm = $request->query->get('q');
$finder = $this->container->get('fos_elastica.finder.app.movie');
$movies = $finder->createPaginatorAdapter($searchTerm)->getResults();
$view = $this->view($movies, 200);
$view->setContext($view->getContext()->setGroups(array('search')));
return $this->handleView($view);
}
Nesse exemplo, a rota /api/movies/search
é associada à ação search
do controller MovieController
. A ação utiliza o serviço fos_elastica.finder.app.movie
para buscar os filmes no banco de dados, utilizando o termo enviado na query string.
Para personalizar a resposta, o método $this->view()
é utilizado com o grupo search
:
$view->setContext($view->getContext()->setGroups(array('search')));
O grupo search
pode ser definido no arquivo config.yml
:
fos_rest:
serializer:
groups:
- list
- details
- admin
- search
Dessa forma, a resposta do controller de busca será personalizada com apenas os campos necessários para serem exibidos na pesquisa.
Como implementar Paginação em uma Lista em Symfony?
A paginação é uma funcionalidade importante em uma lista, para evitar carregar todos os itens de uma vez e melhorar a performance da aplicação. O FOSRESTBundle oferece suporte à paginação utilizando a biblioteca PagerFanta
.
Para implementar a paginação, é preciso adicionar a rota para a ação de lista e utilizar o serviço fos_rest.view_handler
para personalizar a resposta:
use PagerfantaAdapterDoctrineORMAdapter;
use PagerfantaPagerfanta;
api_movies_list:
path: /api/movies
methods: GET
defaults: { _controller: AppBundle:Movie:list }
public function listAction(Request $request)
{
$entityManager = $this->getDoctrine()->getManager();
$queryBuilder = $entityManager->getRepository('AppBundle:Movie')->createQueryBuilder('m');
$adapter = new DoctrineORMAdapter($queryBuilder);
$paginator = new Pagerfanta($adapter);
$paginator->setMaxPerPage($request->query->get('limit', 10));
$paginator->setCurrentPage($request->query->get('page', 1));
$movies = $paginator->getCurrentPageResults();
$view = $this->view($movies, 200);
$view->setContext($this->get('fos_rest.context')->setGroups(array('list')));
$view->setHeader('X-Total-Count', $paginator->getNbResults());
$view->setHeader('X-Page-Count', $paginator->getNbPages());
return $this->handleView($view);
}
Nesse exemplo, a rota /api/movies
é associada à ação list
do controller MovieController
. A ação utiliza o serviço DoctrineORMAdapter
para obter os filmes da base de dados e o serviço Pagerfanta
para criar a paginação.
O método $paginator->setMaxPerPage()
define o número máximo de itens por página e o método $paginator->setCurrentPage()
define a página atual. Em seguida, o método $paginator->getCurrentPageResults()
retorna apenas os itens da página atual.
Para personalizar a resposta, os métodos $view->setHeader()
são utilizados para adicionar as informações de total de resultados e páginas. O parâmetro X-Total-Count
é utilizado para indicar o total de itens na lista e o parâmetro X-Page-Count
é utilizado para indicar o total de páginas.
Por fim, o método $this->handleView()
é utilizado para enviar a resposta para o cliente.