You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在API Platform中用自定义归一化器处理JSON:API空关联

解决API Platform JSON:API格式下空关联返回空数组的问题

问题背景

在API Platform搭配JSON:API格式开发时,用基于Symfony\Component\Serializer\Normalizer\NormalizerInterface实现的自定义条目归一化器解析实体及其关联,遇到了空关联被JSON:API归一化器忽略的问题——即使设置skip_null_values为false也没用。

自定义归一化器代码:

class ApiItemNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
{
    public function __construct(private readonly NormalizerInterface $decorated, ...) { ... }

    public function normalize($object, $format = null, array $context = [])
    {
        $responseObject = $this->decorated->normalize($object, $format, $context);
        ...
     }
}

当前返回结果中,无关联的条目不会显示category字段:

"data": [
    {
        "id": 2,
        "name": "does not have any relation",
        "created_at": "2023-04-24T11:46:16+02:00"
    },
    {
        "id": 1,
        "name": "have two relations",
        "created_at": "2023-04-13T11:37:53+02:00",
        "category": [
            {
               "name": "cat 1",
                "updated_by": null,
                "id": 1
            },
            {
                "name": "cat 2",
                "updated_by": null,
                "id": 3
            }
        ]
    }
]

需求是让无关联的条目也返回category: []空数组。

可行解决方案

方案1:自定义归一化器中手动补全空字段

在normalize方法里,检查实体的关联属性,为空时手动添加空数组到返回结果:

public function normalize($object, $format = null, array $context = [])
{
    $responseObject = $this->decorated->normalize($object, $format, $context);
    
    // 假设实体类是Item,关联属性为category
    if ($object instanceof Item) {
        if (!isset($responseObject['category']) || empty($responseObject['category'])) {
            $responseObject['category'] = [];
        }
    }

    return $responseObject;
}

这种方式针对性强,适合只需要处理特定字段的场景。

方案2:实体类上配置并初始化关联集合

在实体的关联属性上通过注解配置强制输出,同时在构造函数中初始化集合为非空状态:

use ApiPlatform\Metadata\ApiProperty;
use Symfony\Component\Serializer\Annotation\Groups;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

class Item
{
    // ...其他属性
    
    #[Groups(['item:read'])]
    #[ApiProperty(openapiContext: ['nullable' => false, 'default' => []])]
    private Collection $category;

    public function __construct()
    {
        // 初始化空集合,避免属性为null
        $this->category = new ArrayCollection();
    }

    // ...对应的getter/setter方法
}

把关联属性初始化为ArrayCollection后,即使没有关联数据,属性本身也是空集合,JSON:API归一化器会自动序列化为空数组。

方案3:全局调整JSON:API归一化器配置

在config/packages/api_platform.yaml中配置全局序列化上下文,强制保留空值和空集合:

api_platform:
    formats:
        jsonapi:
            serializer:
                context:
                    skip_null_values: false
                    serialize_null: true

注意这个配置会影响所有字段,若只需特定字段生效,优先用前两种方案。

内容的提问来源于stack exchange,提问作者shayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:34:54