Symfony 7 MapRequestPayload nested DTOs

I want to parse JSON Requests into nested DTOs with MapRequestPayload. The goal is to have the data into the DTOs validated.

Example JSON:

{
    "meta": {
        "locale": "ger",
        "validateOnly": false
    },
    "content": {
        "firstName": "firstName",
        "lastName": "lastName",
        "displayMode": "system",
        "favoriteMandates": [
            {
                "mandateId": "{{mandateId}}",
                "position": 0
            }
        ]
    }
}

“meta” always contains the same set of data, while content varies depending on endpoint.

My first approach was something like this:

use SymfonyComponentValidatorConstraints as Assert;
final class UpdateUserRequestDTO 
{
    public function __construct(
        #[AssertValid] public Meta $meta,
        #[AssertValid] public UpdateUserDTO $content,
    )
    {}
}
use SymfonyComponentValidatorConstraints as Assert;
use CustomConstrains;

final readonly class UpdateUserSettingsDto
{
    public Name $name;
    public FavoriteMandatesCollection $favoriteMandates;

    public function __construct(
        string $firstName,
        string $lastName,
        #[AssertIsArray] array $favoriteMandates,
        #[CustomConstrainsIsEnumValue(DisplayModeEnum::class)] string $displayMode,
    ) {
        $this->name = Name::fromStrings($firstName, $lastName);
        $this->favoriteMandates = FavoriteMandatesCollection::fromInputArray($favoriteMandates);
        $this->displayMode = DisplayModeEnum::fromString($displayMode);

    }
}

The problem is that this would mean 2 Classes per endpoint where the difference between the requestDTO classes is just the type for $content. While this most likely would work it feels kinda dirty, especially if the project grows bigger.

My second approach was then defining $content as array (which would only 1 reusable requestDTO) and then calling the constructor with $dto = new UpdateUserSettingsDto(...$content) at this approach I seem to have missed something, since the constrains aren’t checked.