有人知道如何在集合上添加额外数据吗?\n该文档详细介绍了如何在项目上添加额外数据,这转化为装饰 ItemNormalizer 服务,并且效果非常好。
\n\n但是当涉及到在实体集合上添加一些数据时,我\xe2\x80\x99m 努力寻找要装饰的规范化器。额外的数据可以是任何内容:当前登录的用户、详细的寻呼机、一些调试参数……与特定实体无关,而是与请求本身相关。
\n\n目前唯一可行的解决方案是挂钩内核事件,但这绝对不是我喜欢编写的代码:
\n\nuse ApiPlatform\\Core\\EventListener\\EventPriorities;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\nuse Symfony\\Component\\Security\\Core\\Security;\nuse Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface;\n\nfinal class SerializeListener implements EventSubscriberInterface\n{\n /**\n * @var Security\n */\n private $security;\n\n /**\n * @var NormalizerInterface\n */\n private $normalizer;\n\n public function __construct(\n Security $security,\n NormalizerInterface $normalizer\n ) {\n $this->security = $security;\n $this->normalizer = $normalizer;\n }\n\n public function addCurrentUser(GetResponseForControllerResultEvent $event)\n {\n $request = $event->getRequest();\n if ($request->attributes->has(\'_api_respond\')) {\n $serialized = $event->getControllerResult();\n $data = json_decode($serialized, true);\n $data[\'hydra:user\'] = $this->normalizer->normalize(\n $this->security->getUser(),\n $request->attributes->get(\'_format\'),\n $request->attributes->get(\'_api_normalization_context\')\n );\n $event->setControllerResult(json_encode($data));\n }\n }\n\n /**\n * @inheritDoc\n */\n public static function getSubscribedEvents()\n {\n return [\n KernelEvents::VIEW => [\n \'addCurrentUser\', \n EventPriorities::POST_SERIALIZE,\n ],\n ];\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n有任何想法吗?
\n\n谢谢你,\n本
\n好吧,我终于成功做到了这一点。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
# config/services.yaml
services:
App\Api\ApiCollectionNormalizer:
decorates: 'api_platform.hydra.normalizer.collection'
arguments: [ '@App\Api\ApiCollectionNormalizer.inner' ]
Run Code Online (Sandbox Code Playgroud)
保留它作为记录:)