Новое в Symfony 5.4: Улучшения сериализатора
Глобально настроенный контекст сериализатора
Глобально настроенный контекст Сериализатора управляет (де) сериализацией ресурсов. В текущих версиях Symfony этот контекст передаётся всем нормализаторам. В Symfony 5.4 мы улучшаем конфигурацию компонента Serializer, чтобы вы могли настраивать контекст глобально, по умолчанию. Например:
# config/packages/serializer.yaml
serializer:
default_context:
enable_max_depth: true
В этом примере показана YAML конфигурация, но вы также может использовать конфигурационные файлы XML и PHP.
Пользовательский сериализатор для Symfony Messenger
Ожидается, что JSON-кодированные сообщения для Symfony Messenger, будут иметь следующую структуру:
{
"message": {
"body": {},
"headers": []
}
}
Однако, при использовании сообщений созданных различными третьими сторонами, вы не получите такую структуру сообщения. Вот почему в Symfony 5.4 вы можете использовать собственный сериализатор для JSON-декодирования сообщений.
Сбор ошибок Денормализированного типа
В предыдущих версиях сериализатора при использовании типизированных свойств PHP в определённых ситуациях можно было увидеть ошибки. Например, рассмотрим следующий простой DTO:
class MyDto
{
public string $property1;
public int $property2;
public array $property3;
}
Если ваши JSON данные выглядят следующим образом:
{
"property1": null,
"property2": 7,
"property3": []
}
При попытке десериализации этих данных вы увидите ошибку 500, потому что тип property1
- string
, а вы передаёте null
. В Symfony 5.4 мы улучшили это благодаря новой опции COLLECT_DENORMALIZATION_ERRORS
.
Если вы передадите эту опцию, исключение PHP будет включать подробный список ошибок. Затем вы можете обработать его, как в следующем примере, который обрабатывает некий API:
#[Route('/api', methods:['POST'])]
public function apiPost(SerializerInterface $serializer, Request $request): Response
{
try {
$dto = $serializer->deserialize($request->getContent(), MyDto::class, 'json', [
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
]);
} catch (PartialDenormalizationException $e) {
$violations = new ConstraintViolationList();
/** @var NotNormalizableValueException */
foreach ($e->getErrors() as $exception) {
$message = sprintf('The type must be one of "%s" ("%s" given).', implode(', ', $exception->getExpectedTypes()), $exception->getCurrentType());
$parameters = [];
if ($exception->canUseMessageForUser()) {
$parameters['hint'] = $exception->getMessage();
}
$violations->add(new ConstraintViolation($message, '', $parameters, null, $exception->getPath(), null));
};
return $this->json($violations, 400);
}
return $this->json($dto);
}