Search code examples
phpsymfonyfosrestbundlejmsserializerbundlesymfony-3.4

Symfony RestBundle: @View annotation stopped working after v2 upgrade


I think there's a conflict between JMS serializer and FOSRestBundle: I get an empty json object instead of id and accessToken. Am I missing some v2 documentation?

config.yml

fos_rest:
    routing_loader:
        default_format: json
        include_format: false
    format_listener: true
    view:
        view_response_listener: 'force'
        formats:
            json: true
        templating_formats:
            html: false
            json: false
    body_converter:
        enabled: true

Controller

class SecurityController extends FOSRestController
{
     *
     * @View(serializerGroups={"login"})
     *
     */
    public function postLoginAction(Request $request)
    {
            // $user = MyOAuthUserResponse extends AbstractUserResponse

           // before upgrade I just use: return $this->view($user);

            $view = $this->view($user);

            $context = new Context();
            $context->addGroup('login');

            $view->setContext($context);

            return $this->handleView($view);
    }

Entity

/**
 * @Serializer\ExclusionPolicy("All")
 */
class User extends BaseUser
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Serializer\Expose()
     */
    protected $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime")
     * @Gedmo\Timestampable(on="create")
     */
    private $created;

    /**
     * @var string
     * @ORM\Column(type="string", nullable=true)
     * @Serializer\Expose()
     */
    private $accessToken;

Solution

  • It found the issue!

    In vendor/jms/serializer/src/JMS/Serializer/GraphNavigator.php:209

    $exclusionStrategy = $context->getExclusionStrategy(); // Returns NULL
    

    Which seems to work fine (before the upgrade) with:

    return $this->view($user);
    

    But since the upgrade the $exclusionStrategy returns:

    JMS\Serializer\Exclusion\GroupsExclusionStrategy Object
    (
        [groups:JMS\Serializer\Exclusion\GroupsExclusionStrategy:private] => Array
            (
                [login] => 1
            )
    
        [nestedGroups:JMS\Serializer\Exclusion\GroupsExclusionStrategy:private] => 
    

    )

    In order to fix that I removed the context code I passed to the view and pass the view to the handleview like:

    return $this->handleView($this->view($user));
    

    I was mistaken by this upgrade doc:

    use FOS\RestBundle\Context\Context;
    
    $view = new View();
    
    $context = new Context();
    $view->setContext($context);
    
    $context = $view->getContext();