I have a DTO class looking like:
class ParamsDto
{
#[Assert\Type(ArrayCollection::class)]
#[Assert\All([
new Assert\Type('digit'),
new Assert\Positive(),
])]
private ?ArrayCollection $tagIds = null;
public function getTagIds(): ?ArrayCollection
{
return $this->tagIds;
}
public function setTagIds(?ArrayCollection $tagIds): self
{
$this->tagIds = $tagIds;
return $this;
}
}
Given a request to a url like https://domain.php?tag-ids[]=2
, I'd like to parse the tag-ids
request param into this DTO's tagIds
property.
First step I did, I created a name converter, so I can convert between tag-ids
and tagIds
, so my serializer instantiation looks like:
$nameConverter = new EducationEntrySearchParamNameConverter();
$serializer = new Serializer([
new ArrayDenormalizer(),
new ObjectNormalizer(null, $nameConverter, null, new ReflectionExtractor()),
], [new JsonEncoder()]);
$params = $serializer->denormalize($requestParams, ParamsDto::class);
where $params
shows as:
^ App\DataTransferObject\ParamsDto {#749
-tagIds: Doctrine\Common\Collections\ArrayCollection {#753
-elements: []
}
}
So it is instantiated but it is empty.
Most likely because my request does not include the elements
key in it.
If I do a bit of preprocessing, like:
$requestParams = [];
foreach ($request->query->all() as $key => $value) {
if (in_array($key, ['tag-ids'])) {
$requestParams[$key] = ['elements' => $value];
} else {
$requestParams[$key] = $value;
}
}
$params = $serializer->denormalize($requestParams, ParamsDto::class);
then I get the right output:
^ App\DataTransferObject\ParamsDto {#749
-tagIds: Doctrine\Common\Collections\ArrayCollection {#757
-elements: array:1 [
0 => "2"
]
}
}
How do I do it in a way that the serializer translate the request into the DTO in a way where I don't have to do this pre-processing?
L.E: No need for using a custom name converter, I am now using SerializedName