Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Construct object during deserialization on JMS Serializer

I try to load object from database (Symfony, Doctrine) during deserialization using JMS Serializer. Lets say that I have a simple football api application, two entities Team and Game, teams with id 45 and 46 are already in db.

When creating a new game from json:

{
  "teamHost": 45,
  "teamGues": 46,
  "scoreHost": 54,
  "scoreGuest": 42,

}

Game entity:

class Game {

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Team")
     * @ORM\JoinColumn(nullable=false)
     */
    private $teamHost;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Team")
     * @ORM\JoinColumn(nullable=false)
     */
    private $teamGuest;

I would like to create a Game object that has already loaded teams from the database.

$game = $this->serializer->deserialize($requestBody, \App\Entity\Game::class, 'json');

Looking for a solution I found something like jms_serializer.doctrine_object_constructor but there are no specific examples in the documentation. Are you able to help me with the creation of an object from the database during deserialization?

like image 942
pawels Avatar asked Mar 05 '26 13:03

pawels


1 Answers

You need to create a custom handler: https://jmsyst.com/libs/serializer/master/handlers

A simple example:

<?php

namespace App\Serializer\Handler;


use App\Entity\Team;
use Doctrine\ORM\EntityManagerInterface;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;

class TeamHandler implements SubscribingHandlerInterface
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => Team::class,
                'method' => 'deserializeTeam',
            ],
        ];
    }

    public function deserializeTeam(JsonDeserializationVisitor $visitor, $id, array $type, Context $context)
    {
        return $this->em->getRepository(Team::class)->find($id);
    }
}

Altough I would recommend universal approach to handle any entity you want by a single handler.

Example: https://gist.github.com/Glifery/f035e698b5e3a99f11b5

Also, this question has been asked before: JMSSerializer deserialize entity by id

like image 106
MakG Avatar answered Mar 08 '26 11:03

MakG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!