Skip to content

Commit 8f48b9d

Browse files
authored
feat(symfony): deprecate jsonapi.use_iri_as_id defaulting to true (#8327)
1 parent c9e5071 commit 8f48b9d

6 files changed

Lines changed: 152 additions & 6 deletions

File tree

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,13 +708,19 @@ private function registerJsonApiConfiguration(ContainerBuilder $container, array
708708
$loader->load('jsonapi.php');
709709
$loader->load('state/jsonapi.php');
710710

711+
$useIriAsId = $config['jsonapi']['use_iri_as_id'];
712+
if (null === $useIriAsId) {
713+
trigger_deprecation('api-platform/core', '4.4', 'Not setting "api_platform.jsonapi.use_iri_as_id" explicitly is deprecated. Its default value will change from "true" to "false" in API Platform 5.0. Set it to "true" to keep the current behavior or to "false" to use entity identifiers as the "id" field, and silence this deprecation.');
714+
$useIriAsId = true;
715+
}
716+
711717
$itemNormalizer = $container->getDefinition('api_platform.jsonapi.normalizer.item');
712718
$itemNormalizer->replaceArgument(7, [JsonApiItemNormalizer::ALLOW_CLIENT_GENERATED_ID => $config['jsonapi']['allow_client_generated_id'] ?? false]);
713-
$itemNormalizer->addArgument($config['jsonapi']['use_iri_as_id']);
719+
$itemNormalizer->addArgument($useIriAsId);
714720

715721
$itemDenormalizer = $container->getDefinition('api_platform.jsonapi.denormalizer.item');
716722
$itemDenormalizer->replaceArgument(7, [JsonApiItemNormalizer::ALLOW_CLIENT_GENERATED_ID => $config['jsonapi']['allow_client_generated_id'] ?? false]);
717-
$itemDenormalizer->addArgument($config['jsonapi']['use_iri_as_id']);
723+
$itemDenormalizer->addArgument($useIriAsId);
718724
}
719725

720726
private function registerJsonLdHydraConfiguration(ContainerBuilder $container, array $formats, PhpFileLoader $loader, array $config): void

src/Symfony/Bundle/DependencyInjection/Configuration.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,12 @@ public function getConfigTreeBuilder(): TreeBuilder
100100
->end()
101101
->end()
102102
->end()
103-
// TODO 4.4: deprecate use_iri_as_id defaulting to true
104103
->arrayNode('jsonapi')
105104
->addDefaultsIfNotSet()
106105
->children()
107106
->booleanNode('use_iri_as_id')
108-
->defaultTrue()
109-
->info('Set to false to use entity identifiers instead of IRIs as the "id" field in JSON:API responses.')
107+
->defaultNull()
108+
->info('Set to false to use entity identifiers instead of IRIs as the "id" field in JSON:API responses. Defaults to true; this default will change to false in API Platform 5.0.')
110109
->end()
111110
->booleanNode('allow_client_generated_id')
112111
->defaultFalse()
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Symfony\Tests\Bundle\DependencyInjection;
15+
16+
use ApiPlatform\Metadata\Exception\ExceptionInterface;
17+
use ApiPlatform\Metadata\Exception\InvalidArgumentException;
18+
use ApiPlatform\Metadata\UrlGeneratorInterface;
19+
use ApiPlatform\Symfony\Bundle\DependencyInjection\ApiPlatformExtension;
20+
use ApiPlatform\Tests\Fixtures\TestBundle\TestBundle;
21+
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
22+
use Doctrine\ORM\OptimisticLockException;
23+
use PHPUnit\Framework\Attributes\Group;
24+
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
25+
use PHPUnit\Framework\TestCase;
26+
use Symfony\Bundle\SecurityBundle\SecurityBundle;
27+
use Symfony\Bundle\TwigBundle\TwigBundle;
28+
use Symfony\Component\DependencyInjection\ContainerBuilder;
29+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
30+
use Symfony\Component\HttpFoundation\Response;
31+
32+
final class JsonApiUseIriAsIdDeprecationTest extends TestCase
33+
{
34+
private ContainerBuilder $container;
35+
36+
protected function setUp(): void
37+
{
38+
$containerParameterBag = new ParameterBag([
39+
'kernel.bundles' => [
40+
'DoctrineBundle' => DoctrineBundle::class,
41+
'SecurityBundle' => SecurityBundle::class,
42+
'TwigBundle' => TwigBundle::class,
43+
],
44+
'kernel.bundles_metadata' => [
45+
'TestBundle' => [
46+
'parent' => null,
47+
'path' => realpath(__DIR__.'/../../../Fixtures/TestBundle'),
48+
'namespace' => TestBundle::class,
49+
],
50+
],
51+
'kernel.project_dir' => __DIR__.'/../../../Fixtures/app',
52+
'kernel.debug' => false,
53+
'kernel.environment' => 'test',
54+
]);
55+
56+
$this->container = new ContainerBuilder($containerParameterBag);
57+
}
58+
59+
#[Group('legacy')]
60+
#[IgnoreDeprecations]
61+
public function testNotSettingUseIriAsIdIsDeprecatedAndResolvesToTrue(): void
62+
{
63+
$this->expectUserDeprecationMessage('Since api-platform/core 4.4: Not setting "api_platform.jsonapi.use_iri_as_id" explicitly is deprecated. Its default value will change from "true" to "false" in API Platform 5.0. Set it to "true" to keep the current behavior or to "false" to use entity identifiers as the "id" field, and silence this deprecation.');
64+
65+
(new ApiPlatformExtension())->load($this->buildConfig(), $this->container);
66+
67+
$this->assertTrue($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13));
68+
$this->assertTrue($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12));
69+
}
70+
71+
public function testSettingUseIriAsIdToFalseDoesNotDeprecateAndResolvesToFalse(): void
72+
{
73+
(new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => false]), $this->container);
74+
75+
$this->assertFalse($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13));
76+
$this->assertFalse($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12));
77+
}
78+
79+
public function testSettingUseIriAsIdToTrueDoesNotDeprecateAndResolvesToTrue(): void
80+
{
81+
(new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => true]), $this->container);
82+
83+
$this->assertTrue($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13));
84+
$this->assertTrue($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12));
85+
}
86+
87+
private function buildConfig(?array $jsonapi = null): array
88+
{
89+
$config = ['api_platform' => [
90+
'title' => 'title',
91+
'description' => 'description',
92+
'version' => 'version',
93+
'enable_json_streamer' => false,
94+
'serializer' => ['hydra_prefix' => true],
95+
'formats' => [
96+
'json' => ['mime_types' => ['json']],
97+
'jsonld' => ['mime_types' => ['application/ld+json']],
98+
'jsonapi' => ['mime_types' => ['application/vnd.api+json']],
99+
],
100+
'doctrine_mongodb_odm' => [
101+
'enabled' => true,
102+
],
103+
'defaults' => [
104+
'extra_properties' => [],
105+
'url_generation_strategy' => UrlGeneratorInterface::ABS_URL,
106+
],
107+
'error_formats' => [
108+
'jsonproblem' => ['application/problem+json'],
109+
'jsonld' => ['application/ld+json'],
110+
],
111+
'patch_formats' => [],
112+
'exception_to_status' => [
113+
ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
114+
InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
115+
OptimisticLockException::class => Response::HTTP_CONFLICT,
116+
],
117+
'show_webby' => true,
118+
'eager_loading' => [
119+
'enabled' => true,
120+
'max_joins' => 30,
121+
'force_eager' => true,
122+
'fetch_partial' => false,
123+
],
124+
'asset_package' => null,
125+
'enable_entrypoint' => true,
126+
'enable_docs' => true,
127+
'enable_swagger' => true,
128+
'enable_swagger_ui' => true,
129+
'use_symfony_listeners' => false,
130+
]];
131+
132+
if (null !== $jsonapi) {
133+
$config['api_platform']['jsonapi'] = $jsonapi;
134+
}
135+
136+
return $config;
137+
}
138+
}

src/Symfony/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"api-platform/elasticsearch": "^4.3",
5656
"api-platform/graphql": "^4.3",
5757
"api-platform/hal": "^4.3",
58+
"api-platform/json-api": "^4.3",
5859
"phpspec/prophecy-phpunit": "^2.2",
5960
"phpunit/phpunit": "^11.5 || ^12.2",
6061
"symfony/expression-language": "^6.4 || ^7.0 || ^8.0",

tests/Fixtures/app/config/config_common.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ api_platform:
6161
jsonapi: ['application/vnd.api+json']
6262
html: ['text/html']
6363
xml: ['application/xml', 'text/xml']
64+
jsonapi:
65+
use_iri_as_id: true
6466
graphql:
6567
enabled: true
6668
nesting_separator: __

tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm
251251
'format' => 'jsonld',
252252
],
253253
'jsonapi' => [
254-
'use_iri_as_id' => true,
254+
'use_iri_as_id' => null,
255255
'allow_client_generated_id' => false,
256256
],
257257
'enable_scalar' => true,

0 commit comments

Comments
 (0)