I have entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Groups;
//...
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
**/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
* @Groups({"default"})
*/
protected $id;
/**
* @ORM\ManyToMany(targetEntity="StorageBundle\Entity\File")
* @ORM\JoinTable(name="users_photos",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="photo_id", referencedColumnName="id", onDelete="CASCADE")}
* )
* @Groups({"default"})
*/
protected $photoFiles;
/**
* @ORM\Column(type="string", length=255, nullable=true, unique=false)
* @Groups({"notification"})
*/
protected $deviceId;
/**
* @ORM\Column(type="string", length=255, nullable=true, unique=false)
* @Groups({"default"})
*/
protected $name;
/**
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Car", mappedBy="driver")
* @Groups({"driver"})
*/
private $car;
/**
* @var \DateTime $created
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
* @Groups({"default"})
*/
protected $created;
/**
* @var \DateTime $updated
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
* @Groups({"default"})
*/
protected $updated;
}
My Controller:
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\User;
//...
class UsersController extends AppController{
/**
* Get list of Admins
* @Annotations\Get("/api/v1/admins", name="list_of_admins")
* @return \FOS\RestBundle\View\View
*/
public function getAdminsAction(){
if(!$this->isGranted('ROLE_ADMIN')){
throw new AccessDeniedException('Only for Admin');
}
$admins = $this->getDoctrine()->getRepository('AppBundle:User')->findByRole('ROLE_ADMIN');
return $this->view(['data' => $admins], Codes::HTTP_OK);
}
}
A user with role ROLE_ADMIN does not have the car (car have only users with role ROLE_DRIVER). When I try to get all admins I get this:
{
"id": 4,
"username": "[email protected]",
"email": "[email protected]",
"roles": [
"ROLE_ADMIN"
],
"photoFiles": [],
"name": "Andrii",
"car": null
}
I tried add Groups. What I need to add my controller to receive data only from group default and notification
As reminder, Groups
in JMSSerializer are used as exclusion strategy.
An exclusion strategy consists to a specific approach used to expose/exclude properties depending on condition/context.
In order to use them correctly, the first thing you have to do is exclude all properties of your entity :
// ...
use JMS\Serializer\Annotation as JMS;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @JMS\ExclusionPolicy("all")
*/
class User extends BaseUser
Now, you have explicitly expose properties depending on Groups
:
/**
* @ORM\Column(type="string", length=255, nullable=true, unique=false)
* @JMS\Groups({"default"}) // Idem for all properties you want render in group "default"
*/
protected $name;
/**
* @ORM\Column(type="string", length=255, nullable=true, unique=false)
* @JMS\Groups({"notification"})
*/
protected $deviceId;
Then, you have to define the used Group
in your controller action :
/**
* Get list of Admins
* @Annotations\Get("/api/v1/admins", name="list_of_admins")
* @Annotations\View(serializerGroups={"default", "notification"}) // Here set the Group used
* @return \FOS\RestBundle\View\View
*/
public function getAdminsAction()
{
if(!$this->isGranted('ROLE_ADMIN')){
throw new AccessDeniedException('Only for Admin');
}
$admins = $this->getDoctrine()->getRepository('AppBundle:User')->findByRole('ROLE_ADMIN');
return $this->view(['data' => $admins], Codes::HTTP_OK);
}
Now, $admins
contains only the properties exposed to the group default
and notification
.
You can also do it manually instead of use an annotation :
$view = $this->view($admins, 200);
$view->setSerializerGroups(array('default', 'notification'));
return $this->handleView($view);
For more informations, see Exclusion strategies .
I hope it's clear for you.