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
因为我更喜欢 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