Use a non-ID field as the ApiResource identifier on a Doctrine entity

30 Views Asked by At

I am using API Platform 3.2 with Symfony 7.0.

I have a Doctrine entity SimplePoll which extends an abstract parent class Poll.

SimplePoll is an ApiResource. Its ID is an auto-generated $id field, which is used internally for FK relations and the like. It also has a $uuid field, set on persist, which I'd like to use in all public-facing endpoints instead of $id. For example GET /api/simple-polls/{id} should use $uuid instead of the $id. The UUID is a Symfony\Component\Uid\UuidV7 from the symfony/uid package, which integrates with Doctrine.

I thought I could accomplish this by setting ApiProperty(identifier: false) on $id and ApiProperty(identifier: true) on $uuid, like so:

App\Entity\Poll:

#[ORM\Entity]
#[ORM\Table('poll')]
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\HasLifecycleCallbacks]
abstract class Poll
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[ApiProperty(identifier: false)]
    private ?int $id = null;

    #[ORM\Column(type: UuidType::NAME, unique: true)]
    #[Groups(['poll:read'])]
    #[ApiProperty(identifier: true)]
    private Uuid $uuid;

    #[ORM\PrePersist]
    public function createUuid(): void
    {
        $this->uuid = Uuid::v7();
    }
}

App\Entity\SimplePoll:

#[ORM\Entity(repositoryClass: SimplePollRepository::class)]
#[ApiResource(
    normalizationContext: [
        'groups' => ['poll:read'],
    ],
    denormalizationContext: [
        'groups' => ['poll:write']
    ]
)]
class SimplePoll extends Poll
{
}

However, calling API endpoints that take a poll ID (such as GET /api/simple-polls/{id}) returns a 404 when I pass the poll's UUID -- it still only works with the poll's ID. Additionally, the response of successful POST and PATCH requests is null (using id), which I suspect is related.

How can I replace id with uuid in the API without changing the entity's primary key?

1

There are 1 best solutions below

3
gbillig On

You need to change id to uuid on route definition https://symfony.com/doc/current/routing.html#route-parameters