fix(serializer): denormalize object-typed args on discriminated input DTO subclass#8424
Open
soyuka wants to merge 1 commit into
Open
fix(serializer): denormalize object-typed args on discriminated input DTO subclass#8424soyuka wants to merge 1 commit into
soyuka wants to merge 1 commit into
Conversation
… DTO subclass When an operation uses a plain (non-ApiResource) input DTO carrying a Serializer DiscriminatorMap, the normalizer pins resource_class to the abstract input base. The discriminator resolves the concrete subclass for instantiation, but constructor/setter argument metadata was still read from the abstract base, so an object-typed argument declared only on the subclass resolved to no type and its nested payload was passed as a raw array, triggering a TypeError (HTTP 500). Pin resource_class to the discriminator-resolved concrete class on the input path so subclass-only argument types are found and denormalized. Regression from api-platform#7779 (4.2.17). Fixes api-platform#8414
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When an operation uses a plain (non-
#[ApiResource]) input DTO carrying a Symfony Serializer#[DiscriminatorMap], and a concrete subclass declares a constructor argument that is (a) not a property on the abstract base and (b) object-typed (a nested DTO, not a scalar/array), that argument is passed to the constructor as the raw array instead of being denormalized —TypeError, HTTP 500.Regression from #7779 (shipped 4.2.17); not affected
<= 4.2.16.Root cause
In
AbstractItemNormalizer::denormalize(), the input-DTO path (#7779) pinsresource_classto the abstract input base. The discriminator then resolves the concrete subclass for instantiation, but because the resolved class is not itself a resource,resource_classstays the abstract base. Constructor/setter argument metadata is looked up against that base (createAndValidateAttributeValue()), so a subclass-only property resolves to no type and its nested payload falls through as a raw array.The existing
CrudAbstractTest::testCreateConcreteViaDiscriminatorOnAbstractdoesn't catch this: there the abstract base is a resource, so the pre-existingisResourceClass()branch already re-pinsresource_classto the concrete resource.Fix
On the input path, when the discriminator resolves a concrete non-resource subclass, pin
resource_classto that concrete class so subclass-only argument types are found and denormalized. Sits next to the existingisResourceClass()branch that already handles the resource case.Tests
DiscriminatedInputDtoTestmirroring the issue (plain-DTO input + SerializerDiscriminatorMap+ object-typed subclass-only constructor arg). Fails with the exactTypeError/500 before the fix, 201 after.CrudAbstractTest(Doctrine table-inheritance discriminator) and theAbstractItemNormalizerunit suite stay green.