kockburn
kockburn

Reputation: 17636

Generic Deserializing : JSON ID value to Object

What I'm using:

I'm using the JMSSerializerBundle to deserialize my JSON object from a POST request.

Description of the problem:

One of the vaules in my JSON is an Id. I'd like to replace this Id with the correct object before the deserialization occurs.

Unfortunately, JMSSerializerBundle does not have a @preDeserializer annotation.

The problem I'm facing (and that I would have faced if there was an @preDeserializer annotation anyway) is that I would like to create a generic function for all my entities.

Question:

How do I replace my Id with the corresponding object in the most generic way possible ?

Upvotes: 2

Views: 183

Answers (1)

KJBTech
KJBTech

Reputation: 1971

You also do your own hydratation as I did (with Doctrine):

Solution

The IHydratingEntity is an interface which all my entities implement. The hydrate function is used in my BaseService generically. Parameters are the entity and the json object.

At each iteration, the function will test if the method exists then it will call the reflection function to check if the parameter's method (setter) also implements IHydratingEntity. If it's the case, I use the id to get the entity from the database with Doctrine ORM.

I think it's possible to optimize this process, so please be sure to share your thoughts !

protected function hydrate(IHydratingEntity $entity, array $infos)
{
    #->Verification
    if (!$entity) exit;
    #->Processing
    foreach ($infos as $clef => $donnee)
    {
        $methode = 'set'.ucfirst($clef);
        if (method_exists($entity, $methode))
        {
            $donnee = $this->reflection($entity, $methode, $donnee);
            $entity->$methode($donnee);
        }
    }
}

public function reflection(IHydratingEntity $entity, $method, $donnee)
{
    #->Variable declaration
    $reflectionClass = new \ReflectionClass($entity);
    #->Verification
    $idData = intval($donnee);
    #->Processing
    foreach($reflectionClass->getMethod($method)->getParameters() as $param)
    {
        if ($param->getClass() != null)
        {
            if ($param->getClass()->implementsInterface(IEntity::class))
                #->Return
                return $this->getDoctrine()->getRepository($param->getClass()->name)->find($idData);
        }
    }
    #->Return
    return $donnee;
}

Upvotes: 2

Related Questions