Search code examples
apisymfonyjmssymfony4jms-serializer

Symfony 4 + JMS Serializer - Internal Server Error


I have a problem with serialization data.

I have two entities, which are connection relation.

These are my entities:

Task.php

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;

/**
 * @ORM\Entity
 */
class Task
{
    /**
     *
     * @var integer
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     *
     */
    private $id;

    /**
     * @JMS\MaxDepth(1)
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="task")
     *
     */
    private $user;

User.php

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Task", mappedBy="user")
     */
    private $task;

    public function __construct()
    {

I would like to create API, and I serialization my data with JMS. I get this error:

Internal Server Error The server encountered an internal error or misconfiguration and was unable to complete your request.

This is my controller:

public function getAllAction(): JsonResponse
    {
        $tasks = $this->taskService->getAll();
        $serializer = SerializerBuilder::create()->build();
        $data = $serializer->serialize($tasks, 'json', 
        SerializationContext::create()->enableMaxDepthChecks());

        return new JsonResponse($data, 200, [], true);
    }

Function getAll in my controller return data with table Task.

Please, help me with my problem. :)

Thanks, Friends.


Solution

  • I did not use JMS Serializer but i can suggest different solution like symfony serializer component.

    public function getAllAction(SerializerInterface $serializer): JsonResponse
    {
        $data = $serializer->serialize($this->taskService->getAll(), 'json');
        return new JsonResponse($data, 200, [], true);
    }
    

    Optional you can set serialization group to avoid circular reference error.

    For each entity atribute that you want to serialize, set:

    use Symfony\Component\Serializer\Annotation\Groups;

    /**
     * @ORM\Column(name="title", type="string", nullable=false, length=150)
     * @Assert\Type("string")
     * @Assert\NotBlank()
     * @Groups({"group_name"})
     */
    private $title;
    
    /**
     * @ORM\Column(name="description", type="string", nullable=true, length=255)
     * @Assert\Type("string")
     */
    private $description;
    

    And then you serialize only this field with specific group:

    $serializer->serialize($this->taskService->getAll(), 'json', ['groups' => ['group_name']])
    

    Doc: https://symfony.com/doc/4.1/serializer.html#using-serialization-groups-annotations

    PS. Action suffix isnt required now https://symfony.com/doc/current/best_practices/controllers.html#controller-action-naming