diff --git a/features/jsonld/no_output.feature b/features/jsonld/no_output.feature new file mode 100644 index 00000000000..09b7a41919a --- /dev/null +++ b/features/jsonld/no_output.feature @@ -0,0 +1,10 @@ +Feature: Disable Id generation on anonymous resource collections + + @!mongodb + Scenario: Post to an output false should not generate an IRI + When I add "Content-Type" header equal to "application/ld+json" + And I send a "POST" request to "/no_iri_messages" with body: + """ + {} + """ + Then the response status code should be 202 diff --git a/src/Metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php index 22942fa7937..b7f6d722a17 100644 --- a/src/Metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php +++ b/src/Metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php @@ -65,8 +65,8 @@ private function getTransformedOperations(Operations|array $operations, ApiResou && \array_key_exists('class', $operation->getInput()) && null === $operation->getInput()['class'] ) { - $operation = $operation->withDeserialize(false); - $operation = $operation->withValidate(false); + $operation = $operation->withDeserialize(null === $operation->canDeserialize() ? false : $operation->canDeserialize()); + $operation = $operation->withValidate(null === $operation->canValidate() ? false : $operation->canValidate()); } if ( @@ -74,8 +74,9 @@ private function getTransformedOperations(Operations|array $operations, ApiResou && $operation->getOutput() && \array_key_exists('class', $operation->getOutput()) && null === $operation->getOutput()['class'] + && null === $operation->getStatus() ) { - $operation = $operation->withStatus($operation->getStatus() ?? 204); + $operation = $operation->withStatus(204); } $operations instanceof Operations ? $operations->add($key, $operation) : $operations[$key] = $operation; diff --git a/src/State/Processor/RespondProcessor.php b/src/State/Processor/RespondProcessor.php index bd0eb898bff..1cf28f6d2a2 100644 --- a/src/State/Processor/RespondProcessor.php +++ b/src/State/Processor/RespondProcessor.php @@ -88,7 +88,11 @@ public function process(mixed $data, Operation $operation, array $uriVariables = $method = $request->getMethod(); $originalData = $context['original_data'] ?? null; - if ($hasData = ($this->resourceClassResolver && $originalData && \is_object($originalData) && $this->resourceClassResolver->isResourceClass($this->getObjectClass($originalData))) && $this->iriConverter) { + $outputMetadata = $operation->getOutput() ?? ['class' => $operation->getClass()]; + $hasOutput = \is_array($outputMetadata) && \array_key_exists('class', $outputMetadata) && null !== $outputMetadata['class']; + $hasData = !$hasOutput ? false : ($this->resourceClassResolver && $originalData && \is_object($originalData) && $this->resourceClassResolver->isResourceClass($this->getObjectClass($originalData))); + + if ($hasData && $this->iriConverter) { if ( !isset($headers['Location']) && 300 <= $status && $status < 400 diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6352/NoIriMessage.php b/tests/Fixtures/TestBundle/ApiResource/Issue6352/NoIriMessage.php new file mode 100644 index 00000000000..ca9687adcf0 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6352/NoIriMessage.php @@ -0,0 +1,27 @@ + + * + * 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\Tests\Fixtures\TestBundle\ApiResource\Issue6352; + +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\NotExposed; +use ApiPlatform\Metadata\Post; + +#[ApiResource(operations: [ + new NotExposed(), + new Post(status: 202, output: false), +])] +class NoIriMessage +{ + public ?int $id = null; +} diff --git a/tests/State/RespondProcessorTest.php b/tests/State/RespondProcessorTest.php index 615b4b49b79..decbb70287d 100644 --- a/tests/State/RespondProcessorTest.php +++ b/tests/State/RespondProcessorTest.php @@ -35,6 +35,7 @@ public function testRedirectToOperation(): void { $canonicalUriTemplateRedirectingOperation = new Get( status: 302, + class: Employee::class, extraProperties: [ 'canonical_uri_template' => '/canonical', ] @@ -42,12 +43,14 @@ public function testRedirectToOperation(): void $alternateRedirectingResourceOperation = new Get( status: 308, + class: Employee::class, extraProperties: [ 'is_alternate_resource_metadata' => true, ] ); $alternateResourceOperation = new Get( + class: Employee::class, extraProperties: [ 'is_alternate_resource_metadata' => true, ]