Hello.
I have problems with this issue.. I want to serialize an entity and only show some fields.
My entity:
....
use JMS\Serializer\Annotation\Groups;
/**
* @ORM\Entity
* @ORM\Table(name="Channel")
*/
class Channel
{
/**
* @var integer $id
* @Groups({"list", "details"})
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @Groups({"details"})
* @var string $nombre
* @ORM\Column(name="nombre", type="string", length=255)
*/
private $nombre;
/**
* @Groups({"list"})
* @var string $url
*
* @ORM\Column(name="url", type="string", length=255)
*/
private $url;
And in My controller:
use JMS\Serializer\SerializationContext;
/**
* Channel controller.
*
*/
class ChannelController extends FOSRestController{
/**
* Finds and displays a Channel entity.
* @ApiDoc(
* description="show a channel by id",
* output="....Entity\Channel",
* statusCodes={
* 200="Returned when successful",
* 404="Unable to find Channel entity"
* }
* )
* @Cache(expires="+60", public="true")
* @ParamConverter("channel", class="ApiBundle:Channel")
*/
public function showAction(Channel $channel, Request $request)
{
$serializer = $this->container->get('serializer');
$channel = $serializer->serialize($channel, 'json', SerializationContext::create()->setGroups(array('list')));
$view = $this->view($channel, 200);
return $this->handleView($view);
}
But my problem is the following:
I think that this code is serialize twice... because my result is:
"{\"id\":1,\"url\":\"url1\"}"
And the solution correct is:
"{"id":1,"url":"url1"}"
Somebody can help me ? Thanks :)
You shouldn't serialize entity, it's done by FOSRestBundle
public function showAction(Channel $channel, Request $request)
{
$view = $this->view($channel, 200);
$view->setSerializerGroups(array('list'));
return $this->handleView($view);
}
Or even use @View(serializerGroups={"group1", "group2"})
Thanks for to reply @wiistriker .
The method setSerializerGroups is in the class FOS\RestBundle\Controller\Annotations\View.
But I use the class FOS\RestBundle\View as in the documentation ...
https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/2-the-view-layer.md#introduction
So? .. How can I use the method setSerializerGroups... ?
I tried this in my controller:
[...]
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\View;
class ChannelController extends FOSRestController
{
/**
* Finds and displays a Channel entity.
* @Rest\View(serializerGroups={"list"})
* @ParamConverter("channel", class="ApiBundle:Channel")
*/
public function showAction(Channel $channel, Request $request)
{
$view = $this->view($channel, 200);
return $this->handleView($view);
}
}
But I get the entity with all fields...
Have a look at the Exclusion Policy option.
Acme\\DemoBundle\\Entity\\Channel:
exclusion_policy: ALL
properties:
id:
expose: true
groups: ["channel_list", "channel_show"]
title:
expose: true
groups: ["channel_show"]
# ...
@Chrysweel The View class (used by your $view variable) has a setSerializationContext method: https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/View/View.php#L166
@Baachi, @stof thanks for to reply.
@Baachi But my problem is to filter by group. The annotation Exclusion Policy works correctly. But my problem is when I want to show only the "list" group for example.
@Chrysweel Set the serialization context in your View instance:
// This is the context you created in your code above when serializing by hand
$context = SerializationContext::create()->setGroups(array('list'));
$view = // ...
$view->setSerializationContext($context);
return $this->handleView($view);
Ok. issue solved. Thank you very much @stof.
Also issue closed https://github.com/FriendsOfSymfony/FOSRestBundle/issues/521#issuecomment-22098058
Most helpful comment
You shouldn't serialize entity, it's done by FOSRestBundle
Or even use
@View(serializerGroups={"group1", "group2"})