Extra data on a collection operation

ぃ、小莉子 提交于 2019-12-11 16:56:24

问题


Does anybody know how to add extra data on a collection? The doc says much about how to add extra data on an item which translates into decorating the ItemNormalizer service, and it works pretty well.

But I’m struggling in finding out which normalizer to decorate when it comes to add some data on a collection of entities. The extra data could be anything: the current user logged in, a detailed pager, some debug parameters, ... that are not related to a specific entity, but rather on the request itself.

The only working solution for now is to hook on a Kernel event but that's definitely not the code I like to write:

use ApiPlatform\Core\EventListener\EventPriorities;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class SerializeListener implements EventSubscriberInterface
{
    /**
     * @var Security
     */
    private $security;

    /**
     * @var NormalizerInterface
     */
    private $normalizer;

    public function __construct(
        Security $security,
        NormalizerInterface $normalizer
    ) {
        $this->security = $security;
        $this->normalizer = $normalizer;
    }

    public function addCurrentUser(GetResponseForControllerResultEvent $event)
    {
        $request = $event->getRequest();
        if ($request->attributes->has('_api_respond')) {
            $serialized = $event->getControllerResult();
            $data = json_decode($serialized, true);
            $data['hydra:user'] = $this->normalizer->normalize(
                $this->security->getUser(),
                $request->attributes->get('_format'),
                $request->attributes->get('_api_normalization_context')
            );
            $event->setControllerResult(json_encode($data));
        }
    }

    /**
     * @inheritDoc
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::VIEW => [
                'addCurrentUser', 
                EventPriorities::POST_SERIALIZE,
            ],
        ];
    }

}

Any ideas?

Thank you, Ben


回答1:


Alright, I finally managed to do this.

namespace App\Api;

use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class ApiCollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
    /**
     * @var NormalizerInterface|NormalizerAwareInterface
     */
    private $decorated;

    public function __construct(NormalizerInterface $decorated)
    {
        if (!$decorated instanceof NormalizerAwareInterface) {
            throw new \InvalidArgumentException(
                sprintf('The decorated normalizer must implement the %s.', NormalizerAwareInterface::class)
            );
        }
        $this->decorated = $decorated;
    }

    /**
     * @inheritdoc
     */
    public function normalize($object, $format = null, array $context = [])
    {

        $data = $this->decorated->normalize($object, $format, $context);
        if ('collection' === $context['operation_type'] && 'get' === $context['collection_operation_name']) {
            $data['hydra:meta'] = ['foo' => 'bar'];
        }
        return $data;
    }

    /**
     * @inheritdoc
     */
    public function supportsNormalization($data, $format = null)
    {
        return $this->decorated->supportsNormalization($data, $format);
    }

    /**
     * @inheritdoc
     */
    public function setNormalizer(NormalizerInterface $normalizer)
    {
        $this->decorated->setNormalizer($normalizer);
    }

}
# config/services.yaml
services:
    App\Api\ApiCollectionNormalizer:
        decorates: 'api_platform.hydra.normalizer.collection'
        arguments: [ '@App\Api\ApiCollectionNormalizer.inner' ]

Keep it for the records :)



来源:https://stackoverflow.com/questions/52946834/extra-data-on-a-collection-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!