diff --git a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index f7feddc373c..e1ca3a70eed 100644 --- a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -708,13 +708,19 @@ private function registerJsonApiConfiguration(ContainerBuilder $container, array $loader->load('jsonapi.php'); $loader->load('state/jsonapi.php'); + $useIriAsId = $config['jsonapi']['use_iri_as_id']; + if (null === $useIriAsId) { + 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.'); + $useIriAsId = true; + } + $itemNormalizer = $container->getDefinition('api_platform.jsonapi.normalizer.item'); $itemNormalizer->replaceArgument(7, [JsonApiItemNormalizer::ALLOW_CLIENT_GENERATED_ID => $config['jsonapi']['allow_client_generated_id'] ?? false]); - $itemNormalizer->addArgument($config['jsonapi']['use_iri_as_id']); + $itemNormalizer->addArgument($useIriAsId); $itemDenormalizer = $container->getDefinition('api_platform.jsonapi.denormalizer.item'); $itemDenormalizer->replaceArgument(7, [JsonApiItemNormalizer::ALLOW_CLIENT_GENERATED_ID => $config['jsonapi']['allow_client_generated_id'] ?? false]); - $itemDenormalizer->addArgument($config['jsonapi']['use_iri_as_id']); + $itemDenormalizer->addArgument($useIriAsId); } private function registerJsonLdHydraConfiguration(ContainerBuilder $container, array $formats, PhpFileLoader $loader, array $config): void diff --git a/src/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DependencyInjection/Configuration.php index 0c9e3c07dec..27f5cfbd2be 100644 --- a/src/Symfony/Bundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DependencyInjection/Configuration.php @@ -100,13 +100,12 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->end() ->end() - // TODO 4.4: deprecate use_iri_as_id defaulting to true ->arrayNode('jsonapi') ->addDefaultsIfNotSet() ->children() ->booleanNode('use_iri_as_id') - ->defaultTrue() - ->info('Set to false to use entity identifiers instead of IRIs as the "id" field in JSON:API responses.') + ->defaultNull() + ->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.') ->end() ->booleanNode('allow_client_generated_id') ->defaultFalse() diff --git a/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php b/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php new file mode 100644 index 00000000000..83f34ce3c49 --- /dev/null +++ b/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Symfony\Tests\Bundle\DependencyInjection; + +use ApiPlatform\Metadata\Exception\ExceptionInterface; +use ApiPlatform\Metadata\Exception\InvalidArgumentException; +use ApiPlatform\Metadata\UrlGeneratorInterface; +use ApiPlatform\Symfony\Bundle\DependencyInjection\ApiPlatformExtension; +use ApiPlatform\Tests\Fixtures\TestBundle\TestBundle; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; +use Doctrine\ORM\OptimisticLockException; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\TwigBundle\TwigBundle; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\HttpFoundation\Response; + +final class JsonApiUseIriAsIdDeprecationTest extends TestCase +{ + private ContainerBuilder $container; + + protected function setUp(): void + { + $containerParameterBag = new ParameterBag([ + 'kernel.bundles' => [ + 'DoctrineBundle' => DoctrineBundle::class, + 'SecurityBundle' => SecurityBundle::class, + 'TwigBundle' => TwigBundle::class, + ], + 'kernel.bundles_metadata' => [ + 'TestBundle' => [ + 'parent' => null, + 'path' => realpath(__DIR__.'/../../../Fixtures/TestBundle'), + 'namespace' => TestBundle::class, + ], + ], + 'kernel.project_dir' => __DIR__.'/../../../Fixtures/app', + 'kernel.debug' => false, + 'kernel.environment' => 'test', + ]); + + $this->container = new ContainerBuilder($containerParameterBag); + } + + #[Group('legacy')] + #[IgnoreDeprecations] + public function testNotSettingUseIriAsIdIsDeprecatedAndResolvesToTrue(): void + { + $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.'); + + (new ApiPlatformExtension())->load($this->buildConfig(), $this->container); + + $this->assertTrue($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13)); + $this->assertTrue($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12)); + } + + public function testSettingUseIriAsIdToFalseDoesNotDeprecateAndResolvesToFalse(): void + { + (new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => false]), $this->container); + + $this->assertFalse($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13)); + $this->assertFalse($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12)); + } + + public function testSettingUseIriAsIdToTrueDoesNotDeprecateAndResolvesToTrue(): void + { + (new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => true]), $this->container); + + $this->assertTrue($this->container->getDefinition('api_platform.jsonapi.normalizer.item')->getArgument(13)); + $this->assertTrue($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12)); + } + + private function buildConfig(?array $jsonapi = null): array + { + $config = ['api_platform' => [ + 'title' => 'title', + 'description' => 'description', + 'version' => 'version', + 'enable_json_streamer' => false, + 'serializer' => ['hydra_prefix' => true], + 'formats' => [ + 'json' => ['mime_types' => ['json']], + 'jsonld' => ['mime_types' => ['application/ld+json']], + 'jsonapi' => ['mime_types' => ['application/vnd.api+json']], + ], + 'doctrine_mongodb_odm' => [ + 'enabled' => true, + ], + 'defaults' => [ + 'extra_properties' => [], + 'url_generation_strategy' => UrlGeneratorInterface::ABS_URL, + ], + 'error_formats' => [ + 'jsonproblem' => ['application/problem+json'], + 'jsonld' => ['application/ld+json'], + ], + 'patch_formats' => [], + 'exception_to_status' => [ + ExceptionInterface::class => Response::HTTP_BAD_REQUEST, + InvalidArgumentException::class => Response::HTTP_BAD_REQUEST, + OptimisticLockException::class => Response::HTTP_CONFLICT, + ], + 'show_webby' => true, + 'eager_loading' => [ + 'enabled' => true, + 'max_joins' => 30, + 'force_eager' => true, + 'fetch_partial' => false, + ], + 'asset_package' => null, + 'enable_entrypoint' => true, + 'enable_docs' => true, + 'enable_swagger' => true, + 'enable_swagger_ui' => true, + 'use_symfony_listeners' => false, + ]]; + + if (null !== $jsonapi) { + $config['api_platform']['jsonapi'] = $jsonapi; + } + + return $config; + } +} diff --git a/src/Symfony/composer.json b/src/Symfony/composer.json index 914d4bc77e7..c139336e1b9 100644 --- a/src/Symfony/composer.json +++ b/src/Symfony/composer.json @@ -55,6 +55,7 @@ "api-platform/elasticsearch": "^4.3", "api-platform/graphql": "^4.3", "api-platform/hal": "^4.3", + "api-platform/json-api": "^4.3", "phpspec/prophecy-phpunit": "^2.2", "phpunit/phpunit": "^11.5 || ^12.2", "symfony/expression-language": "^6.4 || ^7.0 || ^8.0", diff --git a/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php b/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php index ed8e05043a1..a31121d8a19 100644 --- a/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php +++ b/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php @@ -251,7 +251,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm 'format' => 'jsonld', ], 'jsonapi' => [ - 'use_iri_as_id' => true, + 'use_iri_as_id' => null, 'allow_client_generated_id' => false, ], 'enable_scalar' => true,