When listing an using a REST index endpoint I would like to have different outputs for performance reasons.
ex: on the same GET path for CRUD indexing
- List of Entities with all associations
- List of Entities with some associations
- List of Entities with just some basic fields
This would be used for listing entities for a detailed view with statistics or just listing them for a drop down selector.
Possible Solution 1: I can do this in the controller by returning an object where I customize all the fields based on a query parameter - but then my controllers become very fat because listing all the required fields can be 20-30 fields per object. (basically giving up on the benefit of a serializer doing this automatically based on the type of the entity)
return [
[
'id' => $event->getId(),
'name' => $event->getName(),
...
'order_count' => $orderRepository->getOrderCountForEvent($event->getId())
],
...
]
Possible Solution 2: I could define transform functions in the repository for the different views and filters that I want to return.
public function transform(Event $event, $type = 'shortlist')
{
$view = null;
switch($type) {
case 'shortlist':
$view = [
'id' => $event->getId(),
'name' => $event->getName(),
'participants' => $orderRepository->getParticipantCountForEvent($event->getId()),
...
];
break;
default:
... // all fields
break
}
return $view;
}
Are there any better / cleaner solutions? Most tutorials are only dealing with simple entities with simple relations and their CRUD implementations are very basic where they simply fetch every field and pass it to a serializer.
Maybe you are looking for the Symfony serializer, which has the feature of choosing fields you render.
Example from the doc:
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
class User
{
public $familyName;
public $givenName;
public $company;
}
class Company
{
public $name;
public $address;
}
$company = new Company();
$company->name = 'Les-Tilleuls.coop';
$company->address = 'Lille, France';
$user = new User();
$user->familyName = 'Dunglas';
$user->givenName = 'Kévin';
$user->company = $company;
$serializer = new Serializer([new ObjectNormalizer()]);
$data = $serializer->normalize($user, null, [AbstractNormalizer::ATTRIBUTES => ['familyName', 'company' => ['name']]]);
// $data = ['familyName' => 'Dunglas', 'company' => ['name' => 'Les-Tilleuls.coop']];
See documentation here: https://symfony.com/doc/current/components/serializer.html#selecting-specific-attributes