When implementing a rest json api with Symfony, one can deserialize the data for a create route with Jms Serializer:
$user = $serializer->deserialize($data, 'AppBundle\Entity\User', 'json');
but this makes all parameters of the User Entity available to set from the POST request, which might not be that good.
An alternative to this is to use setters in the controller:
$user = new User();
$user->setUsername($request->request->get('username'));
$user->sePassword($request->request->get('password'));
...
The latter option makes it more clear which parameters are actually able to set, but it requires a lot of code for a large entity.
What is the preferred way here? Is it a third option?
You can serialize json data from your controller natively in Symfony once you have the Serializer component installed.
$user = $this->get('serializer')->deserialize($data, 'AppBundle\Entity\User', 'json');
When your object is created via this method, using the json from your request (decoded and then denormalized), the setters of your object are utilized to populate the properties of your object. Could you post your User Entity?
Alternatively you can use Form Classes to perform this task.
Modification in relation to the comment on your question.
Annotation Groups in your entities works for serialization and deserialization.
class Item
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
* @Groups({"first", "second"})
*/
private $id;
/**
* @ORM\Column(type="string", name="name", length=100)
* @Groups({"first"})
*/
private $name;
/**
* @ORM\Column(type="string", name="name", length=200)
* @Groups({"second"})
*/
private $description;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getDescription()
{
return $this->description;
}
public function setDescription($description)
{
$this->description = $description;
}
}
If you had both "name" and "description" in your POST data, you could insert either into your entity with the following:
$object = $this->get('serializer')->deserialize($data, 'AppBundle\Entity\User', 'json', ['groups' => ['first']]);
Or
$object = $this->get('serializer')->deserialize($data, 'AppBundle\Entity\User', 'json', ['groups' => ['second']]);
In the first case, only the name property would be populated and only the description property in the second case.