Home > Software engineering >  Symfony Serializer custom Denormalizer
Symfony Serializer custom Denormalizer

Time:01-03

I would like to decorate the ArrayDenormalizer for the Symfony serializer with a custom Denormalizer, but it seems it hits a Circular reference problem in the DependencyInjection since Nginx is crashing with a 502.

The custom Denormalizer implements DenormalizerAwareInterface so i actually expected that Symfony would handle the dependency injection automatically via Autowiring.

<?php

namespace App\Serializer;

use App\MyEntity;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

class PreCheckRequestDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
    use DenormalizerAwareTrait;

    public function denormalize(mixed $data, string $type, string $format = null, array $context = [])
    {
        if (in_array($data['locale'], ['de', 'en']) === false) {
            $data['locale'] = 'en';
        }

        return $this->denormalizer->denormalize($data, $type, $format, $context);
    }

    public function supportsDenormalization(mixed $data, string $type, string $format = null)
    {
        return is_array($data) && $type === MyEntity::class;
    }
}

What am i missing here? Btw it is Symfony 6.1.

CodePudding user response:

Seems this is a bug with autowiring of NormalizeAwareInterface in Symfony 6.1: https://github.com/symfony/maker-bundle/issues/1252#issuecomment-1342478104

This bug led into a circular reference problem.

I solved it with not using the DenormalizerAwareInterface and DenormalizerAwareTrait and by disabling autowiring for the custom Denormalizer and declare the service explicitly:

  App\Serializer\PreCheckRequestDenormalizer:
    autowire: false
    arguments:
      $denormalizer: '@serializer.normalizer.object'
      $allowedLocales: '%app.allowed_locales%'
      $defaultLocale: '%env(string:DEFAULT_LOCALE)%'

The comments of the issue describe possible further other ways, but thsi solves it for me.

  • Related