Symfony: How to get JMS Serializer to work with strict types?

This is my situation:

I am trying to write a Symfony REST API that works with strict types (integer, boolean and float) because Symfony's default behavior does not support it, and I want to avoid enforcement types (for example: JMS Serializer converts a string value to an integer type fields )

To do this, I created a custom handler that implements JMS\Serializer\Handler\SubscribingHandlerInterface (for example, a StrictIntegerHandler):

<?php

namespace AppBundle\Serializer;

use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

class StrictIntegerHandler implements SubscribingHandlerInterface
{
    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => 'strict_integer',
                'method' => 'deserializeStrictIntegerFromJSON',
            ],
            [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'strict_integer',
                'method' => 'serializeStrictIntegerToJSON',
            ],
        ];
    }

    public function deserializeStrictIntegerFromJSON(
        JsonDeserializationVisitor $visitor, $data, array $type)
    {
        return $data;
    }

    public function serializeStrictIntegerToJSON(
        JsonSerializationVisitor $visitor, $data, array $type, Context $context)
    {
        return $visitor->visitInteger($data, $type, $context);
    }
}

My essence is:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Validator;

/**
 * Person
 *
 * @ORM\Table(name="persons")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\PersonRepository")
 */
class Person
{
    /**
     * @var int age
     *
     * @ORM\Column(name="age", type="integer")
     *
     * @Serializer\Type("strict_integer")
     * @Serializer\Groups({"Person"})
     *
     * @Validator\Type(type="integer", message="Age field has wrong type")
     */
    private $age;

    public function getAge()
    {
        return $this->age;
    }

    public function setAge(int $age)
    {
        $this->age = $age;
    }
}

When I throw the following POST actions, the JMS Serializer returns the correct results:

  • { "age" : 12 } will result in int(12)
  • { "age" : "asdf" } will result in "Age field has wrong type"

In both cases, my method is called deserializeStrictIntegerFromJSON, so the deserialization process runs fine as I want.

: GET (/person/id_person), :

, . @Type " "? (JMS\Serializer\Exception\LogicException)

, serializeStrictIntegerToJSON ..

? .

+4
1

: jms/serializer 1.5.0.

, jms/serializer (v1.1.0), SerializationContext LogicException in isVisiting(), strict_integer switch-case accept() GraphNavigator.

0

Source: https://habr.com/ru/post/1676740/


All Articles