我正在尝试向特定资源添加一些额外数据,因此我按照有关Decorating a Serializer and Add Extra Data的文档进行操作,但是当我测试资源时出现此错误:
在(...)/ vendor / api-platform / core / src / Serializer / AbstractItemNormalizer.php,第426行调用null上的成员函数normalize()。
我在这个错误中苦苦挣扎了近两天,我不知道我是否遗漏了一些细节,或者这不是向资源添加额外数据的正确方法。 这是我的资源定义:
AppBundle\Entity\MediaGenerator\Teaser:
attributes:
access_control: "is_granted('ROLE_ADMIN')"
normalization_context:
groups: ['teaser','teaser-read']
denormalization_context:
groups: ['teaser','teaser-write']
order:
position: 'ASC'
这是我的自定义规范化程序:
class ApiNormalizer implements NormalizerInterface
{
private $normalizer;
public function __construct(NormalizerInterface $normalizer)
{
$this->normalizer = $normalizer;
}
public function supportsNormalization($data, $format = null)
{
return $data instanceof Teaser;
}
public function normalize($object, $format = null, array $context = [])
{
$data = $this->normalizer->normalize($object, $format, $context);
if (is_array($data)) {
$data['view'] = "SOME TRANSFORMATION ON TEASER VIEW";
}
return $data;
}
public function supportsDenormalization($data, $type, $format = null)
{
return $this->normalizer->supportsNormalization($data, $type, $format);
}
public function denormalize($data, $class, $format = null, array $context = [])
{
return $this->normalizer->denormalise($data, $class, $format, $context);
}
}
这是我的services.yml声明:
AppBundle\Serializer\ApiNormalizer:
decorates: 'api_platform.jsonld.normalizer.item'
arguments: [ '@AppBundle\Serializer\ApiNormalizer.inner' ]
autoconfigure: false
其他所有内容都作为魅力,config.yml中的序列化程序启用为{ enable_annotations: true }
。
有什么难事吗?
提前感谢ApiPlatform的出色工作!
答案 0 :(得分:1)
https://symfony.com/doc/current/serializer.html
# app/config/config.yml
framework:
# ...
serializer:
name_converter: 'serializer.name_converter.camel_case_to_snake_case'
你在这里遇到的是缺少注入的依赖。主要是因为您调用的方法不会在其他地方对代码执行相同的依赖性检查。具体做法是:
// $this->serializer is NULL
return $this->serializer->normalize($attributeValue, $format, $context);
你会注意到Normalizer/AbstractObjectNormalizer.php::normalize
:
if (!$this->serializer instanceof NormalizerInterface) {
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
}
AbstractItemNormalizer::getAttributeValue
没有此检查(确实应该。
setSerializer
快速检查基本序列化程序,可将其定义为SerilaizerAwareTrait:
这意味着每个Serializer都应该通过类似于依赖项反转的模式依赖注入到每个使用它的规范化器中(其中对象本身调用父设置器来设置它自己:
class Serializer {
public function __construct($normalizer) {
$normalizer->setSerializer($this);
}
这一切归结为几个要求:
Symfony Serializer Contstructor
可以更清楚地看到这一点仔细查看Symfony's Sierlizer Component Docs。通过对其第一个示例进行小幅调整,您应该能够以正确分配ApiNormalizer :: serilizer的方式初始化所有内容。
$encoders = array(new XmlEncoder(), new JsonEncoder());
$normalizers = array(new ApiNormalizer());
$serializer = new Serializer($normalizers, $encoders);