Skip to content

Commit adbc578

Browse files
authored
fix(openapi): entrypoint text/html 200 (#5868)
1 parent c76d9b0 commit adbc578

18 files changed

+46
-13
lines changed

features/hydra/entrypoint.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Feature: Entrypoint support
44
I need to access to an entrypoint listing top-level resources
55

66
Scenario: Retrieve the Entrypoint
7+
When I add "Accept" header equal to "application/ld+json"
78
When I send a "GET" request to "/"
89
Then the response status code should be 200
910
And the response should be in JSON

features/openapi/docs.feature

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,9 @@ Feature: Documentation support
362362
And I send a "GET" request to "/docs"
363363
Then the response status code should be 200
364364
And the header "Content-Type" should be equal to "application/vnd.openapi+yaml; charset=utf-8"
365+
366+
Scenario: Retrieve the OpenAPI documentation
367+
Given I add "Accept" header equal to "text/html"
368+
And I send a "GET" request to "/"
369+
Then the response status code should be 200
370+
And the header "Content-Type" should be equal to "text/html; charset=utf-8"

src/Documentation/Action/EntrypointAction.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Documentation\Entrypoint;
1717
use ApiPlatform\Metadata\Get;
1818
use ApiPlatform\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
19+
use ApiPlatform\Metadata\Resource\ResourceNameCollection;
1920
use ApiPlatform\State\ProcessorInterface;
2021
use ApiPlatform\State\ProviderInterface;
2122
use Symfony\Component\HttpFoundation\Request;
@@ -27,6 +28,8 @@
2728
*/
2829
final class EntrypointAction
2930
{
31+
private static ResourceNameCollection $resourceNameCollection;
32+
3033
public function __construct(
3134
private readonly ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory,
3235
private readonly ProviderInterface $provider,
@@ -35,12 +38,21 @@ public function __construct(
3538
) {
3639
}
3740

38-
public function __invoke(Request $request = null)
41+
public function __invoke(Request $request)
3942
{
43+
static::$resourceNameCollection = $this->resourceNameCollectionFactory->create();
4044
$context = ['request' => $request];
41-
$operation = new Get(outputFormats: $this->documentationFormats, read: true, serialize: true, class: Entrypoint::class, provider: fn () => new Entrypoint($this->resourceNameCollectionFactory->create()));
45+
$request->attributes->set('_api_platform_disable_listeners', true);
46+
$operation = new Get(outputFormats: $this->documentationFormats, read: true, serialize: true, class: Entrypoint::class, provider: [self::class, 'provide']);
47+
$request->attributes->set('_api_operation', $operation);
4248
$body = $this->provider->provide($operation, [], $context);
49+
$operation = $request->attributes->get('_api_operation');
4350

4451
return $this->processor->process($body, $operation, [], $context);
4552
}
53+
54+
public static function provide(): Entrypoint
55+
{
56+
return new Entrypoint(static::$resourceNameCollection);
57+
}
4658
}

src/Symfony/Bundle/Resources/config/api.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
<service id="ApiPlatform\Action\NotFoundAction" alias="api_platform.action.not_found" public="true" />
9797
<service id="ApiPlatform\Action\NotExposedAction" alias="api_platform.action.not_exposed" public="true" />
9898

99-
<service id="api_platform.action.entrypoint" class="ApiPlatform\Action\EntrypointAction" public="true">
99+
<service id="api_platform.action.entrypoint" class="ApiPlatform\Documentation\Action\EntrypointAction" public="true">
100100
<argument type="service" id="api_platform.metadata.resource.name_collection_factory" />
101101
<argument type="service" id="api_platform.state_provider.main" on-invalid="null" />
102102
<argument type="service" id="api_platform.state_processor.main" on-invalid="null" />

src/Symfony/Bundle/Resources/config/legacy/events.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<argument>%api_platform.formats%</argument>
1111
<argument>%api_platform.error_formats%</argument>
1212
<argument>%api_platform.docs_formats%</argument>
13+
<argument>%api_platform.event_listeners_backward_compatibility_layer%</argument>
1314

1415
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="28" />
1516
</service>

src/Symfony/EventListener/AddFormatListener.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class AddFormatListener
3434
{
3535
use OperationRequestInitiatorTrait;
3636

37-
public function __construct(private readonly Negotiator $negotiator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null, private readonly array $formats = [], private readonly array $errorFormats = [], private readonly array $docsFormats = [])
37+
public function __construct(private readonly Negotiator $negotiator, ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null, private readonly array $formats = [], private readonly array $errorFormats = [], private readonly array $docsFormats = [], private readonly bool $eventsBackwardCompatibility = true)
3838
{
3939
$this->resourceMetadataCollectionFactory = $resourceMetadataCollectionFactory;
4040
}
@@ -50,7 +50,7 @@ public function onKernelRequest(RequestEvent $event): void
5050
$request = $event->getRequest();
5151
$operation = $this->initializeOperation($request);
5252

53-
if ('api_platform.symfony.main_controller' === $operation?->getController()) {
53+
if ('api_platform.symfony.main_controller' === $operation?->getController() || ($this->eventsBackwardCompatibility && 'api_platform.action.entrypoint' === $request->attributes->get('_controller')) || $request->attributes->get('_api_platform_disable_listeners')) {
5454
return;
5555
}
5656

src/Symfony/EventListener/AddHeadersListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct(private readonly bool $etag = false, private readonl
3535
public function onKernelResponse(ResponseEvent $event): void
3636
{
3737
$request = $event->getRequest();
38-
if (!$request->isMethodCacheable()) {
38+
if (!$request->isMethodCacheable() || $request->attributes->get('_api_platform_disable_listeners')) {
3939
return;
4040
}
4141

src/Symfony/EventListener/AddLinkHeaderListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function onKernelResponse(ResponseEvent $event): void
4949
$operation = $this->initializeOperation($request);
5050

5151
// API Platform 3.2 has a MainController where everything is handled by processors/providers
52-
if ('api_platform.symfony.main_controller' === $operation?->getController() || $this->isPreflightRequest($request)) {
52+
if ('api_platform.symfony.main_controller' === $operation?->getController() || $this->isPreflightRequest($request) || $request->attributes->get('_api_platform_disable_listeners')) {
5353
return;
5454
}
5555

src/Symfony/EventListener/AddTagsListener.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function onKernelResponse(ResponseEvent $event): void
5858
!$request->isMethodCacheable()
5959
|| !$response->isCacheable()
6060
|| (!$attributes = RequestAttributesExtractor::extractAttributes($request))
61+
|| $request->attributes->get('_api_platform_disable_listeners')
6162
) {
6263
return;
6364
}

src/Symfony/EventListener/DenyAccessListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function onSecurityPostValidation(ViewEvent $event): void
6262
*/
6363
private function checkSecurity(Request $request, string $attribute, array $extraVariables = []): void
6464
{
65-
if (!$this->resourceAccessChecker || !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
65+
if ($request->attributes->get('_api_platform_disable_listeners') || !$this->resourceAccessChecker || !$attributes = RequestAttributesExtractor::extractAttributes($request)) {
6666
return;
6767
}
6868

0 commit comments

Comments
 (0)