【问题标题】:Error when trying to add extra data to a resource response尝试将额外数据添加到资源响应时出错
【发布时间】:2017-10-27 13:39:11
【问题描述】:

我正在尝试向特定资源添加一些额外的数据,因此我遵循了有关 Decorating a Serializer and Add Extra Data 的文档,但是当我测试资源时出现此错误:

在 (...)/vendor/api-platform/core/src/Serializer/AbstractItemNormalizer.php 中的 null 上调用成员函数 normalize(),第 426 行。

我已经为这个错误苦苦挣扎了将近两天,我不知道我是否遗漏了一些细节,或者这不是向资源添加额外数据的正确方法。 这是我的资源定义:

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 的出色工作!

【问题讨论】:

    标签: php symfony serialization api-platform.com


    【解决方案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 都旨在通过类似于依赖反转的模式将依赖注入到每个使用它的规范化器中(其中对象本身调用父 setter 来设置自己:

    class Serializer {
    
    public function __construct($normalizer) {
        $normalizer->setSerializer($this);
    }
    

    这一切归结为几个要求:

    1. 必须使用注入的规范化器来实例化序列化器。
    2. 您的归一化剂需要在该注射列表中。

    这都可以在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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-08
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      相关资源
      最近更新 更多