在API-Platform中允许JSON中有空值

10
我目前拥有这个实体,我想在我的 JSON 中显示我的属性 firedDate 即使该值为空也可以。
/**
 * @ApiResource(normalizationContext={"groups"={"employee"}})
 * @ApiFilter(DateFilter::class, properties={"dateProperty": DateFilter::INCLUDE_NULL_BEFORE_AND_AFTER})
 * @ORM\Table(name="employee")
 */
class Employee
{
    // ...
    
    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @Groups({"employee"})
     */
    private $firedDate;


    public function getFiredDate(): ?\DateTimeInterface
    {
        return $this->firedDate;
    }

    // ...
}

目前,当值为null时,它不会在响应中显示。


这个回答解决了你的问题吗?无法在JSON对象中放置null值 - Molly
我认为那个线程与API平台没有关联。 - coolfarmer
6个回答

27

我认为我找到了解决这个问题的正确方法。 在你的normalizationContext中将skip_null_values设置为false

 * @ApiResource(
 *     itemOperations={
 *         "get" = {
 *             //...
 *         }
 *         "put" = {
 *             //...
 *         },
 *         "patch" = {
 *             //...
 *         }
 *     },
 *     collectionOperations={
 *         "get",
 *         "post" = {
 *             //...
 *         }
 *     },
 *     normalizationContext={
 *         "skip_null_values" = false,
 *         "groups" = {"object:read"}
 *     },
 *     denormalizationContext={"groups" = {"object:write"}}
 * )

1
哦,太好了!我更喜欢你的解决方案,“skip_null_values”可以胜任!:D 谢谢! - coolfarmer
1
我在api-platform文档中找不到这个。谢谢你解决了我的困扰! - lifo
1
在 ApiPlatform 2.6 中,如果您的实体包括一个 PATCH 项目操作,则标志 skip_null_values 将被设置为 true(https://github.com/api-platform/core/blob/2.6/src/Serializer/SerializerContextBuilder.php#L110)。您可以通过 @Winzza 的解决方案来覆盖它或从 api_platform.yaml 的 patch_formats 中删除 application/merge-patch+json - Adrien G

4
在 ApiPlatform 3 中,默认值已从 skip_null_values=false 更改为 skip_null_values=true。如果您不想在每个资源上设置此项,并希望将其设置为 ApiPlatform < 3 上的默认值,则可以在全局配置中简单地设置它。请注意保留 HTML 标签。
api_platform:

    defaults:
      normalization_context:
        skip_null_values: false

如果您使用基于PHP的配置,则可以这样做: (原文链接)

return static function (Symfony\Config\ApiPlatformConfig $apiConfig): void {
    $apiConfig
      ->defaults()
        ->normalizationContext(['skip_null_values' => false]);
}

1
全球解决方案不起作用 - famas23
全球解决方案似乎运行良好。只需清除缓存即可。 - Evgeny Ruban

2
我想提供更多关于@SteveMarooni回答的额外信息,因为我觉得它缺少一些信息。如上所述,设置从ApiPlatform 3改变了changelog here
要更改这个,你需要做的是:
#[ApiResource]添加到每个实体中。
#[ApiResource(
    normalizationContext: [
        'skip_null_values' => false
    ]
)]
class Entity
{
}

或者将这段代码添加到您的全局配置中(如果您没有api_platform.yaml,您可以手动添加它)

api_platform:
    defaults:
        normalization_context:
            skip_null_values: false



你可以在完整的配置文件文档这里找到它。

0
你的PHP版本是否在7.0或以上? 在PHP 7.1中,函数可以具有可为空的返回类型,因此您的函数可以这样写: public function getFiredDate(): ?\DateTime { return $this->firedDate; }
在\DateTime之前加上?,这个函数也会返回null

不幸的是,我已经有一个类似的getter了,我刚刚更新了我的帖子以添加它:/ 我认为问题来自于@ ApiFilter和Api-Platform ...也许我漏掉了什么... - coolfarmer

-1
也许你的实体缺少像这样的getter方法?

public function getFiredDate(): \DateTime
{
  return $this->firedDate;
}


我的实体是通过make:entity生成的,所以所有setter和getter都已经存在了。如果值不是“null”,一切都很好,但我发现在我的JSON结果中没有“null”会让人感到困惑。Api Platform说我必须使用"DateFilter::INCLUDE_NULL_BEFORE_AND_AFTER",但即使按照这个指示操作,它仍然无法正常工作。 - coolfarmer

-5

我从Github上的一个朋友那里得到了解决方案,这是它:

* @ApiResource(
*      itemOperations={"get"},
* )

之前:

{
    "@context": "/contexts/Employee",
    "@id": "/employees/1",
    "@type": "Employee",
    "id": 1,
    "name": "Oliver",
    "hired": "2019-10-10T00:00:00+00:00",
    "experience": 0,
    "salary": "1200.00",
    "job": {
        "@id": "/employee_jobs/1",
        "@type": "EmployeeJob",
        "id": 1,
        "name": "Mécanicien"
    }
}

AFTER:

{
    "@context": "/contexts/Employee",
    "@id": "/employees/1",
    "@type": "Employee",
    "id": 1,
    "name": "Oliver",
    "hired": "2019-10-10T00:00:00+00:00",
    "experience": 0,
    "salary": "1200.00",
    "firedDate": null,
    "job": {
        "@id": "/employee_jobs/1",
        "@type": "EmployeeJob",
        "id": 1,
        "name": "Mécanicien"
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接