How to assign an array from request to a class property with ParamConverter in Symfony 5

785 views Asked by At

I use Symfony 5 and have a trouble with the ParamConverter bundle when I try to map request to my DTO class. In my controller I use create method:

     /**
     * @Rest\Post("/project/{projectId}/blogger-mix/")
     * @ParamConverter("command", class=CreateBloggerMixCommand::class, converter="fos_rest.request_body")
     */
    public function create(string $projectId, CreateBloggerMixCommand $command, CreateBloggerMixHandler $handler): View
    {
        $command->projectId = $projectId;
        try {
            $bloggerSetItem = $handler->handle($command);
            return new View(['id' => $bloggerSetItem->getId()], Response::HTTP_OK);
        } catch (\Throwable $exception){
            return $this->handleErrors($exception);
        }
    }

The DTO looks like:

class CreateBloggerMixCommand implements CommandInterface
{

    /**
     * @var array|string[]
     */
    public array $bloggerSetItems;

}

When I send request with an array:

{
  "bloggerSetItems": [
      "f04a76e0-d70e-41df-a926-e180c78b34fc",
      "07f6d304-9c97-41e9-8f2d-4a993019280c"
  ]
}

I receive an error:

{
    "success": false,
    "status": 500,
    "errors": "You must define a type for App\\Project\\Api\\Command\\CreateBloggerMix\\CreateBloggerMixCommand::$bloggerSetItems."
}

In a nutshell, I can't figure out why ParamConverter can't resolve property array. If I change array to string, then ParamConverter responds that can't convert an array to a string it means that ParamConverter eventualy can see the property, but can't resolve array exactly... Any idea welcome!

2

There are 2 answers

0
Alex Gore On BEST ANSWER

Thanx to our partner we found the following solution:

In DTO add:

use JMS\Serializer\Annotation as Serializer;

And in annotation:

    /**
     * @Assert\NotBlank
     * @Assert\Type (type="array")
     * @Serializer\Type(name="array<string>")
     * @var array|string[]
     */
    public array $bloggerSetItems;

1
Arleigh Hix On

I think "You must define a type" refers to database column type. You should just need to add the column definition and then update the database. There are three options for storing an array, choose one:

/**
 * @var array|string[]
 *
 * @Column(type="array")        // one of these lines
 * @Column(type="simple_array") // one of these lines
 * @Column(type="json_array")   // one of these lines
 */
public array $bloggerSetItems;

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#doctrine-mapping-types