0
votes

I am using Symfony 3, Doctrine 2, FOS Rest bundle and JMS Serializer. I am using the exclude all policy across my app and then selectively exposing fields.

On the User Entity, I want to be able to expose additional fields only for the current user.

For example on the normal api/user/{id} endpoint, I want to expose the normal data, but then for api/user/current I want to expose slightly more data.

Eg.

/**
* ...
* @Serializer\ExclusionPolicy("all")
*/
class Users implements UserInterface
{
    /**
     * @var string
     * @Serializer\Expose
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=true)
     */
    private $name;


    /**
     * @var string
     *
     * @ORM\Column(name="secretfield", type="string", length=255, nullable=true)
     */
    private $secretfield;

I have tried the @groups decorator, but that only works to further whittle down the fields and would require me changing loads and being careful to set the "default" group context everywhere.

I have seen the Dynamic Exclusion Strategy, mentioned in the docs, but I can't figure out if it is what I need or not and which variables are available to build an expression out of.

Any ideas what the best way to do this would be?

1

1 Answers

2
votes

My main worry was the "send everything by default" behaviour that would come from setting the exclusion policy to none.

But I looked into the groups a bit more and found that I could set a default group in the config.

fos_rest:
  serializer:
    groups: ["default"]

I tested this on my User controller and without specifying any groups on the entity or in the Serializer context, it returned nothing. So I modified my entity to use @Serializer\Groups({"default"}) instead of @Serializer\Expose. Which brought me back to the same returned data as when I started.

I then added the current_user group to the secret fields of my entity and added the group to the serializer context to get those additional fields for that particular view.

In the entity:

/**
* ...
* @Serializer\ExclusionPolicy("none")
*/
class Users implements UserInterface
{
    /**
     * @var string
     * @Serializer\Groups({"default"})
     *
     * @ORM\Column(name="name", type="string", length=255, nullable=true)
     */
    private $name;


    /**
     * @var string
     * @Serializer\Groups({"current_user"})
     *
     * @ORM\Column(name="secretfield", type="string", length=255, nullable=true)
     */
    private $secretfield;

And in the controller:

/**
 * @Rest\Get("user/current")
 *
 * @return \FOS\RestBundle\View\View
 */
public function getCurrentAction()
{
    $me = $this->getUser();

    $view = new View($me, Response::HTTP_OK);
    /** @var Context $context */
    $context = $view->getContext();
    $context->setGroups(['current_user', 'default']);
    $view->setContext($context);

    return $view;
}