Как создать ваш пользовательский нормализатор

Дата обновления перевода 2021-09-29

Как создать ваш пользовательский нормализатор

Компонент Сериализатор использует нормализаторы, чтобы проеобразовать любые данные в массив. Компонент предоставляет несколько встроенных нормализаторов, но вам может понадобиться создать собственный нормализатор, чтобы преобразовать неподдерживаемую структуру данных.

Создание нового нормализатора

Представьте, что вы хотите добавить, изменить или удалить некоторые свойства во время процесса сериализации. Для этого вам нужно будет создать собственный нормализатор. Но обычно предпочтительно позволить Symfony нормализовать объект, затем подключиться к нормализации, чтобы настроить нормализованные данные. Чтобы сделать это, используйте ObjectNormalizer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// src/Serializer/TopicNormalizer.php
namespace App\Serializer;

use App\Entity\Topic;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class TopicNormalizer implements ContextAwareNormalizerInterface
{
    private $router;
    private $normalizer;

    public function __construct(UrlGeneratorInterface $router, ObjectNormalizer $normalizer)
    {
        $this->router = $router;
        $this->normalizer = $normalizer;
    }

    public function normalize($topic, string $format = null, array $context = [])
    {
        $data = $this->normalizer->normalize($topic, $format, $context);

        // Здесь, добавьте, измените или удалите некоторые данные:
        $data['href']['self'] = $this->router->generate('topic_show', [
            'id' => $topic->getId(),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        return $data;
    }

    public function supportsNormalization($data, string $format = null, array $context = [])
    {
        return $data instanceof Topic;
    }
}

Регистрация в вашем приложении

Перед использованием этого нормализатора в приложении Symfony, он должен быть зарегитрирован в качестве сервиса и тегирован с помощью serializer.normalizer. Если вы используете конфигурацию services.yaml по умолчанию , это делается автоматически!

Производительность

Чтобы понять, какой нормализатор (или денормализатор) должен быть использован для обработки объекта, класс Serializer циклично вызовет supportsNormalization() (или supportsDenormalization()) из всех зарегистрированных нормализаторов (или денормализаторов).

Результат этих методов может отличаться в зависимости от объекта для сериализации, формата и контекста. Поэтому результат не кешируется по умолчанию, и может привести к значительному ухудшению производительности.

Однако, большинство нормализаторов (и денормализаторов) всегда возвращают одинаковый результат, когда тип и формат объекта совпадают, поэтому результат можно кешировать. Чтобы сделать это, сделайте так, чтобы эти нормализаторы (и денормализаторы) реализовывали CacheableSupportsMethodInterface и возвращали true, когда вызывается hasCacheableSupportsMethod().

Note

Все встроенные нормализаторы и денормализаторы , а также те, что включены в платформу API нативно реализуют этот интерфейс.