Skip to content

feat(serializer): denormalize into the declared collection class - #8640

Draft
GromNaN wants to merge 1 commit into
api-platform:mainfrom
GromNaN:feat/serializer-collection-container-class
Draft

GromNaN wants to merge 1 commit into
api-platform:mainfrom
GromNaN:feat/serializer-collection-container-class

Conversation

@GromNaN

@GromNaN GromNaN commented Oct 5, 2026

Copy link
Copy Markdown
Contributor
Q A
Branch? main
Tickets -
License MIT
Doc PR -

A property that declares a collection class, such as Doctrine\Common\Collections\Collection, was denormalized into a plain array. The item normalizer kept only the element class and asked the Serializer for Foo[], and PropertyAccessor::setValue() could not write that array into the collection, so the request failed with a 422.

DenormalizerInterface::denormalize() only takes a string type, so the container class cannot be part of the type. The core Serializer carries the element type of a collection in the value_type and key_type context entries. AbstractItemNormalizer now reads the declared container class from the property type and passes it with those two entries, mirroring AbstractObjectNormalizer::getCollectionContainerClass().

The test is testDenormalizeCollectionWithAClassContainer in src/Serializer/Tests/AbstractItemNormalizerTest.php. It asserts the type and the context handed to the Serializer, and the value written back to the object.

class_exists(CollectionDenormalizer::class) keeps the previous behavior on Symfony versions that do not ship the Doctrine collection denormalizer yet. That class is added in Symfony 8.2 (symfony/symfony#66144), and the api-platform constraint symfony/doctrine-bridge: ^7.4 || ^8.0 accepts it. The test covers both branches, so it runs on the current dependencies and on Symfony 8.2 without a change.

A container that is a plain array or iterable keeps the Foo[] type.

The resource-collection branch above (denormalizeObjectCollection) has the same limitation when the elements are API resources. This pull request does not touch it.

A property that declares a collection class, such as a Doctrine collection, was
denormalized into a plain array. The item normalizer kept only the element class and
asked the Serializer for "Foo[]", then the property accessor could not write that
array into the collection.

The declared container class is now passed to the Serializer, together with the
element and key types in the "value_type" and "key_type" context entries. The core
Serializer uses those entries to carry the element type of a collection, and the
Doctrine bridge collection denormalizer builds the collection from them.

The class is checked with class_exists, so older Symfony versions keep the "Foo[]"
type. A container that is a plain array or iterable is not affected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant