diff --git a/CHANGELOG.md b/CHANGELOG.md index 4271bc02cf..615f57f3d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Breaking changes +* JSON:API: `use_iri_as_id` now defaults to `false` instead of resolving to `true` with a deprecation, as announced in #8327. The `data.id` member carries the resource identifier and the IRI moves to `data.links.self`. Set `api_platform.jsonapi.use_iri_as_id` to `true` (Symfony) or `'jsonapi' => ['use_iri_as_id' => true]` in `config/api-platform.php` (Laravel) to keep the previous payload. * `ApiPlatform\State\Provider\DeserializeProvider` no longer accepts a `Symfony\Contracts\Translation\TranslatorInterface` as its fourth constructor argument, as announced by the deprecation added in 4.4. Denormalization violations and their translation are handled by `DenormalizationViolationFactoryInterface`, which moves from the fifth to the fourth position. Anyone constructing the provider by hand, or overriding the `api_platform.state_provider.deserialize` service definition, must drop the translator argument. `api-platform/state` no longer requires `symfony/translation-contracts`. ### Notes diff --git a/src/Laravel/ApiPlatformProvider.php b/src/Laravel/ApiPlatformProvider.php index 96ba92c53f..58317cf088 100644 --- a/src/Laravel/ApiPlatformProvider.php +++ b/src/Laravel/ApiPlatformProvider.php @@ -1052,7 +1052,7 @@ public function register(): void $config = $app['config']; $defaultContext = $config->get('api-platform.serializer', []); $defaultContext[JsonApiItemNormalizer::ALLOW_CLIENT_GENERATED_ID] = (bool) $config->get('api-platform.jsonapi.allow_client_generated_id', false); - $useIriAsId = (bool) $config->get('api-platform.jsonapi.use_iri_as_id', true); + $useIriAsId = (bool) $config->get('api-platform.jsonapi.use_iri_as_id', false); return new JsonApiItemNormalizer( $app->make(PropertyNameCollectionFactoryInterface::class), diff --git a/src/Laravel/Tests/JsonApiTest.php b/src/Laravel/Tests/JsonApiTest.php index 1c987a4dd6..91fc7d1534 100644 --- a/src/Laravel/Tests/JsonApiTest.php +++ b/src/Laravel/Tests/JsonApiTest.php @@ -45,6 +45,8 @@ protected function defineEnvironment($app): void $config->set('api-platform.docs_formats', ['jsonapi' => ['application/vnd.api+json']]); $config->set('api-platform.resources', [app_path('Models'), app_path('ApiResource')]); $config->set('api-platform.pagination.items_per_page_parameter_name', 'limit'); + // This suite asserts IRIs in "data.id", which is no longer the default since 5.0. + $config->set('api-platform.jsonapi.use_iri_as_id', true); $config->set('api-platform.defaults', [ 'route_prefix' => '/api', 'parameters' => [ diff --git a/src/Laravel/Tests/JsonProblemTest.php b/src/Laravel/Tests/JsonProblemTest.php index 4302750671..251c301232 100644 --- a/src/Laravel/Tests/JsonProblemTest.php +++ b/src/Laravel/Tests/JsonProblemTest.php @@ -111,7 +111,7 @@ public static function formatsProvider(): array [ 'errors' => [ [ - 'id' => '/api/errors/401', + 'id' => '401', 'detail' => 'Unauthorized', 'type' => 'about:blank', 'title' => 'Error 401', diff --git a/src/Laravel/config/api-platform.php b/src/Laravel/config/api-platform.php index c89c853be2..52ae847eb3 100644 --- a/src/Laravel/config/api-platform.php +++ b/src/Laravel/config/api-platform.php @@ -84,10 +84,10 @@ ], 'jsonapi' => [ - // When false, the JSON:API `data.id` uses the resource scalar identifier - // and a `data.links.self` IRI is added. When true (default), `data.id` + // When false (default), the JSON:API `data.id` uses the resource scalar + // identifier and a `data.links.self` IRI is added. When true, `data.id` // is the resource IRI. - 'use_iri_as_id' => true, + 'use_iri_as_id' => false, // Allow client-generated IDs on JSON:API POST per // https://jsonapi.org/format/#crud-creating-client-ids. Off by default diff --git a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index ff3757f933..3a75bcba35 100644 --- a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -716,10 +716,6 @@ private function registerJsonApiConfiguration(ContainerBuilder $container, array $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]); diff --git a/src/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DependencyInjection/Configuration.php index fb070df050..299e0b88ae 100644 --- a/src/Symfony/Bundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DependencyInjection/Configuration.php @@ -101,8 +101,8 @@ public function getConfigTreeBuilder(): TreeBuilder ->addDefaultsIfNotSet() ->children() ->booleanNode('use_iri_as_id') - ->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.') + ->defaultFalse() + ->info('Set to true to use IRIs instead of entity identifiers as the "id" field in JSON:API responses. Defaults to false, which uses the entity identifier and exposes the IRI as "links.self".') ->end() ->booleanNode('allow_client_generated_id') ->defaultFalse() diff --git a/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php b/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdTest.php similarity index 81% rename from src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php rename to src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdTest.php index 83f34ce3c4..6b9c473ca4 100644 --- a/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdDeprecationTest.php +++ b/src/Symfony/Tests/Bundle/DependencyInjection/JsonApiUseIriAsIdTest.php @@ -20,8 +20,6 @@ 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; @@ -29,7 +27,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\HttpFoundation\Response; -final class JsonApiUseIriAsIdDeprecationTest extends TestCase +final class JsonApiUseIriAsIdTest extends TestCase { private ContainerBuilder $container; @@ -56,19 +54,19 @@ protected function setUp(): void $this->container = new ContainerBuilder($containerParameterBag); } - #[Group('legacy')] - #[IgnoreDeprecations] - public function testNotSettingUseIriAsIdIsDeprecatedAndResolvesToTrue(): void + /** + * Since 5.0 the option defaults to "false": the "id" field carries the entity + * identifier and the IRI moves to "links.self". + */ + public function testNotSettingUseIriAsIdResolvesToFalse(): 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)); + $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 testSettingUseIriAsIdToFalseDoesNotDeprecateAndResolvesToFalse(): void + public function testSettingUseIriAsIdToFalseResolvesToFalse(): void { (new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => false]), $this->container); @@ -76,7 +74,7 @@ public function testSettingUseIriAsIdToFalseDoesNotDeprecateAndResolvesToFalse() $this->assertFalse($this->container->getDefinition('api_platform.jsonapi.denormalizer.item')->getArgument(12)); } - public function testSettingUseIriAsIdToTrueDoesNotDeprecateAndResolvesToTrue(): void + public function testSettingUseIriAsIdToTrueResolvesToTrue(): void { (new ApiPlatformExtension())->load($this->buildConfig(['use_iri_as_id' => true]), $this->container); diff --git a/tests/Fixtures/app/config/config_common.yml b/tests/Fixtures/app/config/config_common.yml index 9add790eab..0d0e22eafa 100644 --- a/tests/Fixtures/app/config/config_common.yml +++ b/tests/Fixtures/app/config/config_common.yml @@ -61,6 +61,8 @@ api_platform: html: ['text/html'] xml: ['application/xml', 'text/xml'] jsonapi: + # Not the default since 5.0: kept explicitly so the shared test environment + # keeps covering the IRI-as-id mode. The "jsonapi" environment covers the default. use_iri_as_id: true graphql: enabled: true diff --git a/tests/Functional/JsonApi/IriModeTest.php b/tests/Functional/JsonApi/IriModeTest.php index 429748ad16..e3f29cc471 100644 --- a/tests/Functional/JsonApi/IriModeTest.php +++ b/tests/Functional/JsonApi/IriModeTest.php @@ -31,9 +31,9 @@ public static function getResources(): array return [JsonApiDummy::class]; } - public function testGetSingleResourceDefaultIriMode(): void + public function testGetSingleResourceIriMode(): void { - // Default mode (use_iri_as_id: true) — id is the IRI, no links.self + // use_iri_as_id: true, set by the shared test environment — id is the IRI, no links.self self::createClient()->request('GET', '/jsonapi_dummies/10', [ 'headers' => ['accept' => 'application/vnd.api+json'], ]); diff --git a/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php b/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php index b1d0a51c44..24c952b015 100644 --- a/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php +++ b/tests/Symfony/Bundle/DependencyInjection/ConfigurationTest.php @@ -244,7 +244,7 @@ private function runDefaultConfigTests(array $doctrineIntegrationsToLoad = ['orm 'format' => 'jsonld', ], 'jsonapi' => [ - 'use_iri_as_id' => null, + 'use_iri_as_id' => false, 'allow_client_generated_id' => false, ], 'enable_scalar' => true,