Every item operation has an identifier in it’s URL. Although this identifier is usually a number, it can also be an UUID, a date, or the type of your choice.
To help with your development experience, we introduced an identifier normalization process.
In the following chapter, we’re assuming that
App\Uuidis a project-owned class that manages a time-based UUID.
Let’s say you have the following class, which is identified by a UUID type. In this example, UUID is not a simple string but it’s an object with many attributes.
<?php
namespace App\Entity;
use App\Uuid;
/**
* @ApiResource
*/
final class Person {
/**
* @var Uuid
* @ApiProperty(identifier=true)
*/
public $code;
}Once registered as an ApiResource, having an existing person, it will be accessible through the following URL: /people/110e8400-e29b-11d4-a716-446655440000.
Note that the property identifying our resource is named code.
Let’s create a DataProvider for the Person entity:
<?php
namespace App\DataProvider;
use App\Entity\Person;
use App\Uuid;
final class PersonDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface {
/**
* {@inheritdoc}
*/
public function getItem(string $resourceClass, $identifiers, string $operationName = null, array $context = [])
{
// Our identifier is:
// $identifiers['code']
// although it's a string, it's not an instance of Uuid and we wanted to retrieve the timestamp of our time-based uuid:
// $identifiers['code']->getTimestamp()
}
/**
* {@inheritdoc}
*/
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return $resourceClass === Person::class;
}
}To cover this use case, we need to denormalize the identifier to an instance of our App\Uuid class. This case is covered by an identifier denormalizer:
<?php
namespace App\Identifier;
use ApiPlatform\Core\Exception\InvalidIdentifierException;
use App\Uuid;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class UuidNormalizer implements DenormalizerInterface
{
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = null, array $context = [])
{
try {
return Uuid::fromString($data);
} catch (InvalidUuidStringException $e) {
throw new InvalidIdentifierException($e->getMessage());
}
}
/**
* {@inheritdoc}
*/
public function supportsDenormalization($data, $type, $format = null)
{
return is_a($type, Uuid::class, true);
}
}Tag this service as a api_platform.identifier.normalizer:
<service id="App\Identifier\UuidNormalizer" class="App\Identifier\UuidNormalizer" public="false">
<tag name="api_platform.identifier.normalizer" />
</service>services:
App\Identifier\UuidNormalizer:
tags:
- { name: api_platform.identifier.normalizer }Your PersonDataProvider will now work as expected!
ApiPlatform supports the following identifier types:
scalar (string, integer)\DateTime (uses the symfony DateTimeNormalizer internally, see DateTimeIdentifierNormalizer)\Ramsey\Uuid\Uuid (see UuidNormalizer)You can also help us improve the documentation of this page.
Using an AI coding agent? See the documentation index for LLMs at /docs/llms.txt.
Made with love by
Les-Tilleuls.coop can help you design and develop your APIs and web projects, and train your teams in API Platform, Symfony, Next.js, Kubernetes and a wide range of other technologies.
Learn more