Api 平台 DateTimeNormalizer 不允许为空

Api Platform DateTimeNormalizer not allowing null

因为我更喜欢 Whosebug 而不是 github,所以我将这个 issue 对话移到这里。

例如,您可能有一个具有 deletedAt 字段的用户。由于某些商业原因,用户被删除,但由于其他原因,您可能希望通过将 deletedAt 字段设置为空来激活他。如果您尝试使用 API 平台执行此操作,您将收到此错误:

The data is either an empty string or null, you should pass a string that can be parsed with the passed format or a valid DateTime string.

问题是,最好的处理方法是什么?

这是我的处理方式。

我扩展了 API 平台 DateTimeNormalizer:

namespace App\Normalizer;

use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer as APIPlatformDateTimeNormalizer;

class DateTimeNormalizer extends APIPlatformDateTimeNormalizer
{
    public function denormalize($data, $type, $format = null, array $context = [])
    {
        if (null === $data) {
            return null;
        }

        return parent::denormalize($data, $type, $format, $context);
    }
}

并将其定义为与实际上覆盖了它的父规范化器同名的服务 (api/config/services.yml):

services:
    serializer.normalizer.datetime:
            class: App\Normalizer\DateTimeNormalizer
            tags:
                - { name: serializer.normalizer }

这里有一个稍微调整过的版本,它严格限于提到的问题。

它并没有取代原来的DateTimeNormalizer,而是注册了更高的优先级,并且只处理传入的$data如果它是空的,并且原来的DateTimeNormalizer支持反规范化。

src/Normalizer/NullableDateTimeDenormalizer.php:

declare(strict_types=1);

namespace App\Normalizer;

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

final class NullableDateTimeDenormalizer implements DenormalizerInterface
{
    public function __construct(
        private DenormalizerInterface $dateTimeNormalizer
    ) {
    }

    public function denormalize($data, string $type, string $format = null, array $context = [])
    {
        return null;
    }

    public function supportsDenormalization($data, string $type, string $format = null)
    {
        if ($data === '' || $data === null) {
            return $this->dateTimeNormalizer->supportsDenormalization($data, $type, $format);
        }

        return false;
    }
}

config/services.yaml:

services:
    App\Normalizer\NullableDateTimeDenormalizer:
        arguments:
            $dateTimeNormalizer: '@serializer.normalizer.datetime'
        tags:
            -
                name: serializer.normalizer
                priority: 100