symfony4、FOSRestBundle 和 ramsey/uuid-doctrine - 将 uuid 对象转换为用于 REST 的字符串 API

symfony4, FOSRestBundle and ramsey/uuid-doctrine - convert uuid object to string for REST API

我现在使用 symfony4 有一段时间了并且很喜欢它。现在我想从 FOSRestBundle 和 ramsey 的 uuid 开始。

到目前为止没有问题,一切正常,当我调用 API 时,我得到了一个 JSON 字段响应。

字段是:

我触发的控制器动作:

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

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

我得到的输出:

{
    "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"
}

如您所见,id 字段是一个对象,但我希望它只包含 uuid 的字符串表示形式,例如:“e3e6cdee-5c93-4aa1-a66c-a9a300ef5181”。我在网上搜索并尝试了很多方法,但找不到如何解决这个问题的答案。

我想要的输出:

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

我现在自己解决了

我只需要将字段的列类型从

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

/**
 * @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;

我不知道这是否正确,但对我有用。

改变我的 getter 是我解决问题的方法。

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

更改为:

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

我终于找到了解决办法。 我写了一个处理程序 PersonH​​andler.

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);
    }
}

它将允许自定义序列化。 在Person实体中,我修改了方法getId()

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

因此我们将在返回的 json

中包含 uuid

正确的解决方案是为 uuid 类型添加序列化程序处理程序。 幸运的是,它已经在这个包中实现了: https://github.com/mhujer/jms-serializer-uuid-bundle

只需安装捆绑包,并在 $id 属性 中添加一个 @Serializer\Type("uuid") 注释。