RequestBody is a way to populate objects and inject them as controller method arguments.
The Request body converter makes it possible to deserialize the request body into an object.
composer require paveldanilin/request-body-bundle
By default, RequestBody is trying to populate the single defined parameter.
/**
* @Route("/users", methods={"POST"})
*
* @RequestBody
*
* @param User $user
* @return Response
*/
public function createUser(User $user): Response
{
return new Response();
}
If a method has several parameters we should explicitly define the parameter for populating.
/**
* @Route("/users", methods={"PATCH"})
*
* @RequestBody("user")
*
* @param int $userId
* @param User $user
* @return Response
*/
public function editUser(int $userId, User $user): Response
{
return new Response();
}
We can specify a deserialization context.
More about the object deserialization you can find here
/**
* @Route("/users", methods={"PATCH"})
*
* @RequestBody("user", deserializationContext={"someAttribute"="value"})
*
* @param int $userId
* @param User $user
* @return Response
*/
public function editUser(int $userId, User $user): Response
{
return new Response();
}
Also, it is possible to replace the deserialization error message with a custom message.
/**
* @Route("/users", methods={"PATCH"})
*
* @RequestBody("user", deserializationError="Bad DTO")
*
* @param int $userId
* @param User $user
* @return Response
*/
public function editUser(int $userId, User $user): Response
{
return new Response();
}
By default, validation will be performed for each assertion which is defined per DTO.
For the following DTO will be performed two assertions after a deserialization process.
class User
{
/**
* @Assert\NotBlank(allowNull=false)
* @Assert\Type(type="string")
*
* @var string
*/
public $name;
}
We can avoid a validation process by defining the validationGroups
attribute as an empty array.
/**
* @Route("/users", methods={"PATCH"})
*
* @RequestBody("user", validationGroups={})
*
* @param int $userId
* @param User $user
* @return Response
*/
public function editUser(int $userId, User $user): Response
{
return new Response();
}
Or we can explicitly define validation groups by means of validationGroups
attribute.
/**
* @Route("/users", methods={"PATCH"})
*
* @RequestBody("user", validationGroups={"edit"})
*
* @param int $userId
* @param User $user
* @return Response
*/
public function editUser(int $userId, User $user): Response
{
return new Response();
}
You can read more about a validation process.
The bundle comes with a handy console command which shows all controllers that use the @RequestBody annotation
$ php bin/console debug:request-body
+--------------------+----------------------+---------------------------------------------------------------------------------------+----------------------------------------------------+--------------------+
| Class | Method | Bind Param | Param Type | Validation Context |
+--------------------+----------------------+---------------------------------------------------------------------------------------+----------------------------------------------------+--------------------+
| TestUserController | createUser | user | paveldanilin\RequestBodyBundle\Tests\Fixtures\User | all |
| TestUserController | editUser | Method does not have such parameter 'user' | | all |
| TestUserController | noTypeHint | The 'user' parameter does not have a type hint | | all |
| TestUserController | autoMap | user | paveldanilin\RequestBodyBundle\Tests\Fixtures\User | all |
| TestUserController | autoMapNoParams | Could not autodetect parameter for body mapping. The method does not have parameters. | | all |
| TestUserController | autoMapTooManyParams | Could not autodetect parameter for body mapping. The method has too many parameters. | | all |
+--------------------+----------------------+---------------------------------------------------------------------------------------+----------------------------------------------------+--------------------+
composer test