I had AI make the description hope thats ok
API Platform version(s) affected: v4.3.6
Description
The jsonapi.use_iri_as_id config key (documented here) is not read by the Laravel ApiPlatformProvider. In the Symfony integration, ApiPlatformExtension passes this config value as a constructor argument to JsonApiItemNormalizer, but the Laravel provider has no equivalent logic — the config is silently ignored.
Additionally, JsonApiItemNormalizer is declared final, making it impossible for users to extend and override the ID behavior.
The id field is hardcoded at line 129 of vendor/api-platform/json-api/Serializer/ItemNormalizer.php:
$resourceData = [
'id' => $context['iri'], // always returns full IRI like "/api/books/1"
'type' => $this->getResourceShortName($resourceClass),
];
How to reproduce
Create a fresh Laravel app with api-platform/laravel:^4.3
Add 'jsonapi' => ['use_iri_as_id' => false] to config/api-platform.php
Set up a simple resource (e.g. Book) with an id primary key
Request GET /api/books/1 with Accept: application/vnd.api+json
Observe the response uses the full IRI as id:
{ "data": { "id": "/api/books/1", "type": "Book" } }
Expected with use_iri_as_id: false:
{ "data": { "id": "1", "type": "Book", "links": { "self": "/api/books/1" } } }
Possible Solution
The Laravel ApiPlatformProvider should either:
Read api-platform.jsonapi.use_iri_as_id from config and pass it to JsonApiItemNormalizer (though the constructor currently doesn't accept this parameter), or
Expose a hook/override point so users can customize the ID format without needing to decorate a final class
Additional Context
Working around this currently requires a decorator wrapping JsonApiItemNormalizer (since it's final) that post-processes the normalized output, plus overriding the container binding — this is non-trivial and fragile.
The Symfony ApiPlatformExtension does this by reading $config['jsonapi']['use_iri_as_id'] and adding it as an argument to the normalizer service definition:
$container->getDefinition('api_platform.jsonapi.normalizer.item')
->addArgument($config['jsonapi']['use_iri_as_id']);
The same pattern should be applied to the Laravel provider; alternatively, the provider could push it into $defaultContext or the serializer context.
I had AI make the description hope thats ok
API Platform version(s) affected: v4.3.6
Description
The jsonapi.use_iri_as_id config key (documented here) is not read by the Laravel ApiPlatformProvider. In the Symfony integration, ApiPlatformExtension passes this config value as a constructor argument to JsonApiItemNormalizer, but the Laravel provider has no equivalent logic — the config is silently ignored.
Additionally, JsonApiItemNormalizer is declared final, making it impossible for users to extend and override the ID behavior.
The id field is hardcoded at line 129 of vendor/api-platform/json-api/Serializer/ItemNormalizer.php:
$resourceData = [
'id' => $context['iri'], // always returns full IRI like "/api/books/1"
'type' => $this->getResourceShortName($resourceClass),
];
How to reproduce
Create a fresh Laravel app with api-platform/laravel:^4.3
Add 'jsonapi' => ['use_iri_as_id' => false] to config/api-platform.php
Set up a simple resource (e.g. Book) with an id primary key
Request GET /api/books/1 with Accept: application/vnd.api+json
Observe the response uses the full IRI as id:
{ "data": { "id": "/api/books/1", "type": "Book" } }
Expected with use_iri_as_id: false:
{ "data": { "id": "1", "type": "Book", "links": { "self": "/api/books/1" } } }
Possible Solution
The Laravel ApiPlatformProvider should either:
Read api-platform.jsonapi.use_iri_as_id from config and pass it to JsonApiItemNormalizer (though the constructor currently doesn't accept this parameter), or
Expose a hook/override point so users can customize the ID format without needing to decorate a final class
Additional Context
Working around this currently requires a decorator wrapping JsonApiItemNormalizer (since it's final) that post-processes the normalized output, plus overriding the container binding — this is non-trivial and fragile.
The Symfony ApiPlatformExtension does this by reading $config['jsonapi']['use_iri_as_id'] and adding it as an argument to the normalizer service definition:
$container->getDefinition('api_platform.jsonapi.normalizer.item')
->addArgument($config['jsonapi']['use_iri_as_id']);
The same pattern should be applied to the Laravel provider; alternatively, the provider could push it into $defaultContext or the serializer context.