2

I am using symfony4 for a while now and love it. Now I wanted to start with the FOSRestBundle and uuid from ramsey.

No problems so far, eveything works fine, when I call the API I get an JSON response with the fields.

The fields are:

  • id, type: uuid
  • username, type: string
  • email, type: string

The controller action that I trigger:

/**
 * @Rest\Get("/api/users", name="api_users_list")
 */
public function index()
{
    $users = $this->getDoctrine()->getRepository(User::class)->findAll();

    return View::create($users, 200);
}

The output I get:

{
    "email": "mail@example.com",
    "id": {
        "codec": {
            "builder": {
                "converter": {}
            }
        },
        "converter": {},
        "factory": {
            "codec": {
                "builder": {
                    "converter": {}
                }
            },
            "node_provider": {
                "node_providers": [
                    {},
                    {}
                ]
            },
            "number_converter": {},
            "random_generator": {},
            "time_generator": {
                "node_provider": {
                    "node_providers": [
                        {},
                        {}
                    ]
                },
                "time_converter": {},
                "time_provider": {}
            },
            "uuid_builder": {
                "converter": {}
            }
        },
        "fields": {
            "clock_seq_hi_and_reserved": "a6",
            "clock_seq_low": "6c",
            "node": "a9a300ef5181",
            "time_hi_and_version": "4aa1",
            "time_low": "e3e6cdee",
            "time_mid": "5c93"
        }
    },
    "username": "apokalipscke"
}

As you can see the id field is an object, but I want it to only contains the string representation of the uuid, like: "e3e6cdee-5c93-4aa1-a66c-a9a300ef5181". I searched the internet and tried many thing but can't find an answer how to solve this.

The output I want:

{
    "id": "e3e6cdee-5c93-4aa1-a66c-a9a300ef5181",
    "username": "apokalipscke",
    "email": "mail@example.com"
}
Marc
  • 45
  • 8

4 Answers4

0

I solved it by myself now.

I just need to change the column type of the field from

/**
 * @var UuidInterface
 *
 * @ORM\Id()
 * @ORM\Column(type="uuid", unique=true)
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
 */
private $id;

to

/**
 * @var string
 *
 * @ORM\Id()
 * @ORM\Column(type="string", unique=true, length=36)
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
 */
private $id;

I don't know if this is the right way, but it works for me.

Marc
  • 45
  • 8
  • Actually I have the same problem. In my case, I use uuid_binary instead of uuid because its faster to retrieve a binary id in a database so it is more performant. – quokka-web Mar 21 '19 at 16:19
0

Changing my getter is what allow me to fix the issue.

 public function getPersonId() 
{
    return $this->personId;
}

Changed it to:

public function getPersonId() 
{
    return $this->personId->toString();
}
B. Clincy
  • 126
  • 1
  • 4
0

I finally found a solution. I wrote a handler PersonHandler.

namespace App\Serializer\Handler;

use App\Entity\Person;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\SerializationContext as Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;

class PersonHandler implements SubscribingHandlerInterface
{
    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'App\Entity\Person',
                'method' => 'serialize',
            ],
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => 'App\Entity\Person',
                'method' => 'deserialize',
            ]
        ];
    }

    public function serialize(JsonSerializationVisitor $visitor, Person $person, array $type, Context $context)
    {

        $data = [
            'id' => $person->getId(),
            'name' => $person->getName(),
            'email' => $person->getEmail()
        ];

        return $visitor->visitArray($data, $type, $context);
    }

    public function deserialize(JsonDeserializationVisitor $visitor, $data)
    {
        return new Person($data);
    }
}

It will allow to custom the serialization. In the Person entity, I modified the method getId()

function getId() {
    return $this->id->toString();       
}

So we will have the uuid in the returned json

quokka-web
  • 104
  • 8
  • This way you would have to write similar handlers for all your entities. It would be much easier to create a handler just for `Uuid`. – Alexey Kosov Jan 05 '20 at 20:02
0

The correct solution for that would be adding a serializer handler for the uuid type. And luckily it's already implemented in this bundle: https://github.com/mhujer/jms-serializer-uuid-bundle

Just install the bundle, and add a @Serializer\Type("uuid") annotation to the $id property.

Alexey Kosov
  • 3,010
  • 2
  • 23
  • 32