Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input DTO unable to deserialize ID for updates. #6291

Open
jonnyeom opened this issue Apr 4, 2024 · 1 comment
Open

Input DTO unable to deserialize ID for updates. #6291

jonnyeom opened this issue Apr 4, 2024 · 1 comment

Comments

@jonnyeom
Copy link
Contributor

jonnyeom commented Apr 4, 2024

API Platform version(s) affected: 3.2.x ?+

Description
When updating a resource while using a DTO as an input, (and not using the DTO as the direct resource), Serializer does not deserialize the ID onto the DTO.

How to reproduce
Here is a sample situation with an Entity, an Input DTO, and a Processor to reveal missing ID.

// The Entity class.
#[ApiResource(
    operations: [
        new Patch(
            ...
            uriTemplate: '/api/entity/{id}',
            input: EntityInput::class,
            processor: EntityProcessor::class
        ),
    ],
)]
class Entity
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ApiProperty(identifier: true)]
    private Uuid $id;

    ...
}


// The DTO class.
class EntityInput 
{    
    public ?Uuid $id = null;

    // Whatever data to be sent.
    public string $date;
    public array $information;
    ...
}

// The API Request.
->PATCH({
    '/api/entity/{123456}',
    {
        date: 01-01-2024
        information: [
            'important',
            'data',
        ]
    }
})

// The Processor.
class EntityProcessor 
{    
    /**
     * @param EntityInput $data
     */
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []) {
        \assert $data instanceof EntityInput; // True !
        $data->getId(); // null ?? 
    }
}

Here, I was expecting 123456 to be id.
I know the ID is available. If you hook into the deserializer, $context[ObjectNormalizer::OBJECT_TO_POPULATE] contains the Original Entity to be updated (not at the processor level however). and the identifier is extracted correctly every time. This works as expected when the DTO is the Resource itself. Shouldnt it work the other way around?

Possible Solution
SO im guessing its one of 2 things.

  1. IDs are only deserialized onto DTOs if the DTO is the ApiResource itself
    If so, I think this should be documented and the DTO example in documentation should stop using input:
  2. (Its a bug) IDs should be deserialized, but its not working when used as input: class.
  3. I mis-attributed by entity classes altogether. everything should work fine.
@karrakoliko
Copy link

karrakoliko commented Apr 14, 2024

Try use different Uuid version, in one of my projects only using UuidV1/V4 worked for both api-platform x doctrine

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

No branches or pull requests

2 participants