Skip to content

Commit fd2444a

Browse files
committed
fix(graphql): add a clearer error message when TwigBundle is disable but graphQL clients are enabled
1 parent defe717 commit fd2444a

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

src/GraphQl/Action/EntrypointAction.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class EntrypointAction
3434
{
3535
private int $debug;
3636

37-
public function __construct(private readonly SchemaBuilderInterface $schemaBuilder, private readonly ExecutorInterface $executor, private readonly GraphiQlAction $graphiQlAction, private readonly GraphQlPlaygroundAction $graphQlPlaygroundAction, private readonly NormalizerInterface $normalizer, private readonly ErrorHandlerInterface $errorHandler, bool $debug = false, private readonly bool $graphiqlEnabled = false, private readonly bool $graphQlPlaygroundEnabled = false, private readonly ?string $defaultIde = null)
37+
public function __construct(private readonly SchemaBuilderInterface $schemaBuilder, private readonly ExecutorInterface $executor, private readonly ?GraphiQlAction $graphiQlAction, private readonly ?GraphQlPlaygroundAction $graphQlPlaygroundAction, private readonly NormalizerInterface $normalizer, private readonly ErrorHandlerInterface $errorHandler, bool $debug = false, private readonly bool $graphiqlEnabled = false, private readonly bool $graphQlPlaygroundEnabled = false, private readonly ?string $defaultIde = null)
3838
{
3939
$this->debug = $debug ? DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACE : DebugFlag::NONE;
4040
}

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

+15-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
use Symfony\Component\Uid\AbstractUid;
5454
use Symfony\Component\Validator\Validator\ValidatorInterface;
5555
use Symfony\Component\Yaml\Yaml;
56+
use Twig\Environment;
5657

5758
/**
5859
* The extension of this bundle.
@@ -462,9 +463,12 @@ private function registerGraphQlConfiguration(ContainerBuilder $container, array
462463
{
463464
$enabled = $this->isConfigEnabled($container, $config['graphql']);
464465

466+
$graphiqlEnabled = $enabled && $this->isConfigEnabled($container, $config['graphql']['graphiql']);
467+
$graphqlPlayGroundEnabled = $enabled && $this->isConfigEnabled($container, $config['graphql']['graphql_playground']);
468+
465469
$container->setParameter('api_platform.graphql.enabled', $enabled);
466-
$container->setParameter('api_platform.graphql.graphiql.enabled', $enabled && $this->isConfigEnabled($container, $config['graphql']['graphiql']));
467-
$container->setParameter('api_platform.graphql.graphql_playground.enabled', $enabled && $this->isConfigEnabled($container, $config['graphql']['graphql_playground']));
470+
$container->setParameter('api_platform.graphql.graphiql.enabled', $graphiqlEnabled);
471+
$container->setParameter('api_platform.graphql.graphql_playground.enabled', $graphqlPlayGroundEnabled);
468472
$container->setParameter('api_platform.graphql.collection.pagination', $config['graphql']['collection']['pagination']);
469473

470474
if (!$enabled) {
@@ -476,6 +480,15 @@ private function registerGraphQlConfiguration(ContainerBuilder $container, array
476480

477481
$loader->load('graphql.xml');
478482

483+
// @phpstan-ignore-next-line We ignore the next line because we specify to phpstan to use the container of the test env cache and in test the parameter kernel.bundles always contains the key TwigBundle
484+
if (!class_exists(Environment::class) || !isset($container->getParameter('kernel.bundles')['TwigBundle'])) {
485+
if ($graphiqlEnabled || $graphqlPlayGroundEnabled) {
486+
throw new RuntimeException(sprintf('GraphiQL and GraphQL Playground interfaces depend on Twig. Please activate TwigBundle for the %s environnement or disable GraphiQL and GraphQL Playground.', $container->getParameter('kernel.environment')));
487+
}
488+
$container->removeDefinition('api_platform.graphql.action.graphiql');
489+
$container->removeDefinition('api_platform.graphql.action.graphql_playground');
490+
}
491+
479492
$container->registerForAutoconfiguration(QueryItemResolverInterface::class)
480493
->addTag('api_platform.graphql.query_resolver');
481494
$container->registerForAutoconfiguration(QueryCollectionResolverInterface::class)

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
<service id="api_platform.graphql.action.entrypoint" class="ApiPlatform\GraphQl\Action\EntrypointAction" public="true">
5050
<argument type="service" id="api_platform.graphql.schema_builder" />
5151
<argument type="service" id="api_platform.graphql.executor" />
52-
<argument type="service" id="api_platform.graphql.action.graphiql" />
53-
<argument type="service" id="api_platform.graphql.action.graphql_playground" />
52+
<argument type="service" id="api_platform.graphql.action.graphiql" on-invalid="null"/>
53+
<argument type="service" id="api_platform.graphql.action.graphql_playground" on-invalid="null"/>
5454
<argument type="service" id="serializer" />
5555
<argument type="service" id="api_platform.graphql.error_handler" />
5656
<argument>%kernel.debug%</argument>

tests/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php

+35
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@
7070
use Prophecy\PhpUnit\ProphecyTrait;
7171
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
7272
use Symfony\Bundle\SecurityBundle\SecurityBundle;
73+
use Symfony\Bundle\TwigBundle\TwigBundle;
7374
use Symfony\Component\DependencyInjection\ContainerBuilder;
75+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
7476
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
7577
use Symfony\Component\HttpFoundation\Response;
7678
use Symfony\Component\Uid\AbstractUid;
@@ -163,6 +165,7 @@ protected function setUp(): void
163165
'kernel.bundles' => [
164166
'DoctrineBundle' => DoctrineBundle::class,
165167
'SecurityBundle' => SecurityBundle::class,
168+
'TwigBundle' => TwigBundle::class,
166169
],
167170
'kernel.bundles_metadata' => [
168171
'TestBundle' => [
@@ -173,6 +176,7 @@ protected function setUp(): void
173176
],
174177
'kernel.project_dir' => __DIR__.'/../../../Fixtures/app',
175178
'kernel.debug' => false,
179+
'kernel.environment' => 'test',
176180
]);
177181

178182
$this->container = new ContainerBuilder($containerParameterBag);
@@ -693,6 +697,37 @@ public function testGraphQlConfiguration(): void
693697
$this->assertServiceHasTags('api_platform.graphql.normalizer.runtime_exception', ['serializer.normalizer']);
694698
}
695699

700+
public function testRuntimeExceptionIsThrownIfTwigIsNotEnabledButGraphqlClientsAre(): void
701+
{
702+
$config = self::DEFAULT_CONFIG;
703+
$config['api_platform']['graphql']['enabled'] = true;
704+
$this->container->getParameterBag()->set('kernel.bundles', [
705+
'DoctrineBundle' => DoctrineBundle::class,
706+
'SecurityBundle' => SecurityBundle::class,
707+
]);
708+
$this->expectException(RuntimeException::class);
709+
$this->expectExceptionMessage('GraphiQL and GraphQL Playground interfaces depend on Twig. Please activate TwigBundle for the test environnement or disable GraphiQL and GraphQL Playground.');
710+
711+
(new ApiPlatformExtension())->load($config, $this->container);
712+
}
713+
714+
public function testGraphqlClientsDefinitionsAreRemovedIfDisabled(): void
715+
{
716+
$config = self::DEFAULT_CONFIG;
717+
$config['api_platform']['graphql']['enabled'] = true;
718+
$config['api_platform']['graphql']['graphiql']['enabled'] = false;
719+
$config['api_platform']['graphql']['graphql_playground']['enabled'] = false;
720+
$this->container->getParameterBag()->set('kernel.bundles', [
721+
'DoctrineBundle' => DoctrineBundle::class,
722+
'SecurityBundle' => SecurityBundle::class,
723+
]);
724+
725+
(new ApiPlatformExtension())->load($config, $this->container);
726+
727+
$this->assertNotContainerHasService('api_platform.graphql.action.graphiql');
728+
$this->assertNotContainerHasService('api_platform.graphql.action.graphql_playground');
729+
}
730+
696731
public function testDoctrineOrmConfiguration(): void
697732
{
698733
$config = self::DEFAULT_CONFIG;

0 commit comments

Comments
 (0)