diff --git a/src/Api/IdentifiersExtractor.php b/src/Api/IdentifiersExtractor.php index f7f7dc65b85..c356d870b37 100644 --- a/src/Api/IdentifiersExtractor.php +++ b/src/Api/IdentifiersExtractor.php @@ -57,6 +57,10 @@ public function getIdentifiersFromResourceClass(string $resourceClass): array } } + if (!$identifiers) { + throw new RuntimeException(sprintf('No identifier defined "%s". You should add #[\ApiPlatform\Core\Annotation\ApiProperty(identifier: true)]" on the property identifying the resource."', $resourceClass)); + } + return $identifiers; } diff --git a/tests/Api/IdentifiersExtractorTest.php b/tests/Api/IdentifiersExtractorTest.php index 24237943b87..ac1abb415a4 100644 --- a/tests/Api/IdentifiersExtractorTest.php +++ b/tests/Api/IdentifiersExtractorTest.php @@ -202,6 +202,20 @@ public function testGetsIdentifiersFromCorrectResourceClass(): void $this->assertSame(['foo' => 'woot'], $identifiersExtractor->getIdentifiersFromItem($item)); } + public function testNoIdentifiers(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('No identifier defined "ApiPlatform\\Core\\Tests\\Fixtures\\TestBundle\\Entity\\Dummy". You should add #[\ApiPlatform\Core\Annotation\ApiProperty(identifier: true)]" on the property identifying the resource.'); + $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); + $propertyNameCollectionFactoryProphecy->create(Dummy::class)->willReturn(new PropertyNameCollection(['foo'])); + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); + $propertyMetadataFactoryProphecy->create(Dummy::class, 'foo')->willReturn(new PropertyMetadata()); + $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); + $identifiersExtractor = new IdentifiersExtractor($propertyNameCollectionFactoryProphecy->reveal(), $propertyMetadataFactoryProphecy->reveal(), null, $resourceClassResolverProphecy->reveal()); + + $identifiersExtractor->getIdentifiersFromResourceClass(Dummy::class); + } + /** * @group legacy * @expectedDeprecation Not injecting ApiPlatform\Core\Api\ResourceClassResolverInterface in the IdentifiersExtractor might introduce cache issues with object identifiers. diff --git a/tests/Fixtures/TestBundle/Entity/DummyForAdditionalFieldsInput.php b/tests/Fixtures/TestBundle/Entity/DummyForAdditionalFieldsInput.php index 58a061645ef..8564bb3c468 100644 --- a/tests/Fixtures/TestBundle/Entity/DummyForAdditionalFieldsInput.php +++ b/tests/Fixtures/TestBundle/Entity/DummyForAdditionalFieldsInput.php @@ -13,6 +13,7 @@ namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity; +use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; /** @@ -20,6 +21,11 @@ */ final class DummyForAdditionalFieldsInput { + /** + * @ApiProperty(identifier=true) + */ + public $id; + private $dummyName; public function __construct(string $dummyName) diff --git a/tests/Fixtures/TestBundle/Model/ResourceBarInterface.php b/tests/Fixtures/TestBundle/Model/ResourceBarInterface.php index 01d46d9e1b5..543f76195a3 100644 --- a/tests/Fixtures/TestBundle/Model/ResourceBarInterface.php +++ b/tests/Fixtures/TestBundle/Model/ResourceBarInterface.php @@ -13,7 +13,12 @@ namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\Model; +use ApiPlatform\Core\Annotation\ApiProperty; + interface ResourceBarInterface { + /** + * @ApiProperty(identifier=true) + */ public function getBar(): ?string; }