I am currently trying to denormalize an array, which came out of an API as a JSON response and was JSON decoded.
The problem is, that I want it to be denormalized into a class and one of the properties is another class.
It feels like it should be possible to get such an easy job done with the Symfony denormalizer, but I always get the following exception:
Failed to denormalize attribute "inner_property" value for class "App\Model\Api\Outer": Expected argument of type "App\Model\Api\Inner", "array" given at property path "inner_property".
My denormalizing code looks like that:
$this->denormalizer->denormalize($jsonOuter, Outer::class);
The denormalizer is injected in the constructor:
public function __construct(DenormalizerInterface $denormalizer) {
The array I try to denormalize:
array (
'inner_property' =>
array (
'property' => '12345',
),
)
Finally the both classes I try to denormalize to:
class Outer
{
/** @var InnerProperty */
private $innerProperty;
public function getInnerProperty(): InnerProperty
{
return $this->innerProperty;
}
public function setInnerProperty(InnerProperty $innerProperty): void
{
$this->innerProperty = $innerProperty;
}
}
class InnerProperty
{
private $property;
public function getProperty(): string
{
return $this->property;
}
public function setProperty(string $property): void
{
$this->property = $property;
}
}
After hours of searching I finally found the reason. The problem was the combination of the "inner_property" snake case and $innerProperty or getInnerProperty camel case. In Symfony 5 the camel case to snake case converter is not enabled by default.
So I had to do this by adding this config in the config/packages/framework.yaml:
framework:
serializer:
name_converter: 'serializer.name_converter.camel_case_to_snake_case'
Here is the reference to the Symfony documentation: https://symfony.com/doc/current/serializer.html#enabling-a-name-converter
Alternatively I could have also add a SerializedName annotation to the property in the Outer class: https://symfony.com/doc/current/components/serializer.html#configure-name-conversion-using-metadata
PS: My question was not asked properly, because I didn't changed the property and class names properly. So I fixed that in the question for future visitors.