diff --git a/docs/annotations/annotations-reference.md b/docs/annotations/annotations-reference.md index fcc0b1675..882a6e5ae 100644 --- a/docs/annotations/annotations-reference.md +++ b/docs/annotations/annotations-reference.md @@ -386,7 +386,7 @@ The class exposing the mutation(s) must be declared as a [service](https://symfo Optional attributes: -- **targetType** : The GraphQL type to attach the field to. It must be a mutation. (by default, it'll be the root Mutation type of the default schema). +- **targetType** : The GraphQL type to attach the field to. It must be a mutation. (by default, it'll be the root Mutation type of the default schema. see [Default Schema](../definitions/schema.md#default-schema)). Example: @@ -436,7 +436,7 @@ The class exposing the query(ies) must be declared as a [service](https://symfon Optional attributes: -- **targetType** : The GraphQL type to attach the field to (by default, it'll be the root Query type of the default schema). +- **targetType** : The GraphQL type to attach the field to (by default, it'll be the root Query type of the default schema. see [Default Schema](../definitions/schema.md#default-schema)). Example: diff --git a/docs/definitions/schema.md b/docs/definitions/schema.md index 09b282911..55cc6a99d 100644 --- a/docs/definitions/schema.md +++ b/docs/definitions/schema.md @@ -111,4 +111,8 @@ overblog_graphql: | batch request | `/graphql/bar/batch` | | GraphiQL* | `/graphiql/bar` | +### Default schema + +The schema considered as the default is the one with the name `default` if it exists, otherwise, it will be the first one defined. + \* `/graphiql` depends on [OverblogGraphiQLBundle](https://github.com/overblog/GraphiQLBundle) diff --git a/src/Config/Parser/AnnotationParser.php b/src/Config/Parser/AnnotationParser.php index e2543e050..21bfb0ec1 100644 --- a/src/Config/Parser/AnnotationParser.php +++ b/src/Config/Parser/AnnotationParser.php @@ -253,19 +253,20 @@ private static function typeAnnotationToGQLConfiguration( ): array { $isMutation = $isDefault = $isRoot = false; if (isset($configs['definitions']['schema'])) { + $defaultSchemaName = isset($configs['definitions']['schema']['default']) ? 'default' : array_key_first($configs['definitions']['schema']); foreach ($configs['definitions']['schema'] as $schemaName => $schema) { $schemaQuery = $schema['query'] ?? null; $schemaMutation = $schema['mutation'] ?? null; - if ($schemaQuery && $gqlName === $schemaQuery) { + if ($gqlName === $schemaQuery) { $isRoot = true; - if ('default' == $schemaName) { + if ($defaultSchemaName === $schemaName) { $isDefault = true; } - } elseif ($schemaMutation && $gqlName === $schemaMutation) { + } elseif ($gqlName === $schemaMutation) { $isMutation = true; $isRoot = true; - if ('default' == $schemaName) { + if ($defaultSchemaName === $schemaName) { $isDefault = true; } } diff --git a/src/DataCollector/GraphQLCollector.php b/src/DataCollector/GraphQLCollector.php index 1597d210f..8fd8fa29e 100644 --- a/src/DataCollector/GraphQLCollector.php +++ b/src/DataCollector/GraphQLCollector.php @@ -28,7 +28,11 @@ public function collect(Request $request, Response $response, Throwable $excepti { $error = false; $count = 0; + $schema = null; foreach ($this->batches as $batch) { + if (!$schema) { + $schema = $batch['schema']; + } if (isset($batch['error'])) { $error = true; } @@ -36,7 +40,7 @@ public function collect(Request $request, Response $response, Throwable $excepti } $this->data = [ - 'schema' => $request->attributes->get('_route_params')['schemaName'] ?? 'default', + 'schema' => $schema, 'batches' => $this->batches, 'count' => $count, 'error' => $error, @@ -62,9 +66,9 @@ public function getCount(): int /** * Return the targeted schema. */ - public function getSchema(): string + public function getSchema(): ?string { - return $this->data['schema'] ?? 'default'; + return $this->data['schema']; } /** @@ -105,6 +109,7 @@ public function onPostExecutor(ExecutorResultEvent $event): void $result = $event->getResult()->toArray(); $batch = [ + 'schema' => $executorArgument->getSchemaName(), 'queryString' => $queryString, 'queryTime' => $queryTime, 'variables' => $this->cloneVar($variables), diff --git a/src/Event/ExecutorArgumentsEvent.php b/src/Event/ExecutorArgumentsEvent.php index 95edbf3bc..c527c8099 100644 --- a/src/Event/ExecutorArgumentsEvent.php +++ b/src/Event/ExecutorArgumentsEvent.php @@ -11,6 +11,7 @@ final class ExecutorArgumentsEvent extends Event { + private string $schemaName; private ExtensibleSchema $schema; private string $requestString; private ArrayObject $contextValue; @@ -27,6 +28,7 @@ final class ExecutorArgumentsEvent extends Event * @return static */ public static function create( + string $schemaName, ExtensibleSchema $schema, string $requestString, ArrayObject $contextValue, @@ -35,6 +37,7 @@ public static function create( string $operationName = null ): self { $instance = new static(); + $instance->setSchemaName($schemaName); $instance->setSchema($schema); $instance->setRequestString($requestString); $instance->setContextValue($contextValue); @@ -46,6 +49,11 @@ public static function create( return $instance; } + public function setSchemaName(string $schemaName): void + { + $this->schemaName = $schemaName; + } + public function setOperationName(?string $operationName): void { $this->operationName = $operationName; @@ -84,6 +92,11 @@ public function setStartTime(float $startTime): void $this->startTime = $startTime; } + public function getSchemaName(): string + { + return $this->schemaName; + } + public function getSchema(): ExtensibleSchema { return $this->schema; diff --git a/src/Request/Executor.php b/src/Request/Executor.php index 79562a550..ae056df0f 100644 --- a/src/Request/Executor.php +++ b/src/Request/Executor.php @@ -14,7 +14,6 @@ use GraphQL\Validator\Rules\DisableIntrospection; use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\Rules\QueryDepth; -use Overblog\GraphQLBundle\Definition\Type\ExtensibleSchema; use Overblog\GraphQLBundle\Event\Events; use Overblog\GraphQLBundle\Event\ExecutorArgumentsEvent; use Overblog\GraphQLBundle\Event\ExecutorContextEvent; @@ -84,14 +83,13 @@ public function getSchema(string $name = null): Schema } if (null === $name) { - // TODO(mcg-web): Replace by array_key_first PHP 7 >= 7.3.0. - foreach ($this->schemas as $name => $schema) { - break; - } + $name = isset($this->schemas['default']) ? 'default' : array_key_first($this->schemas); } + if (!isset($this->schemas[$name])) { throw new NotFoundHttpException(sprintf('Could not found "%s" schema.', $name)); } + $schema = $this->schemas[$name]; if (is_callable($schema)) { $schema = $schema(); @@ -137,8 +135,13 @@ public function execute(?string $schemaName, array $request, $rootValue = null): { $this->useExperimentalExecutor ? GraphQL::useExperimentalExecutor() : GraphQL::useReferenceExecutor(); + $schema = $this->getSchema($schemaName); + /** @var string $schemaName */ + $schemaName = array_search($schema, $this->schemas); + $executorArgumentsEvent = $this->preExecute( - $this->getSchema($schemaName), + $schemaName, + $schema, $request[ParserInterface::PARAM_QUERY] ?? null, new ArrayObject(), $rootValue, @@ -168,6 +171,7 @@ public function execute(?string $schemaName, array $request, $rootValue = null): * @param mixed $rootValue */ private function preExecute( + string $schemaName, Schema $schema, string $requestString, ArrayObject $contextValue, @@ -181,8 +185,8 @@ private function preExecute( /** @var ExecutorArgumentsEvent $object */ // @phpstan-ignore-next-line (only for Symfony 4.4) $object = $this->dispatcher->dispatch( - /** @var ExtensibleSchema $schema */ - ExecutorArgumentsEvent::create($schema, $requestString, $contextValue, $rootValue, $variableValue, $operationName), + // @phpstan-ignore-next-line + ExecutorArgumentsEvent::create($schemaName, $schema, $requestString, $contextValue, $rootValue, $variableValue, $operationName), Events::PRE_EXECUTOR ); diff --git a/src/Resources/views/profiler/graphql.html.twig b/src/Resources/views/profiler/graphql.html.twig index 3496091ad..bfbfda37c 100644 --- a/src/Resources/views/profiler/graphql.html.twig +++ b/src/Resources/views/profiler/graphql.html.twig @@ -114,7 +114,7 @@ {{ result.status_code|default('n/a') }} {{ result.time|date }} - {% if schemas|length > 0 %} + {% if schemas|length > 0 and graphql.schema %} schema: {{ graphql.schema }} {% endif %} {{ result.token }} diff --git a/tests/DataCollector/GraphQLCollectorTest.php b/tests/DataCollector/GraphQLCollectorTest.php index fd91149ed..75d3f8fe6 100644 --- a/tests/DataCollector/GraphQLCollectorTest.php +++ b/tests/DataCollector/GraphQLCollectorTest.php @@ -22,21 +22,20 @@ public function testCollect(): void $collector = new GraphQLCollector(); $request = new Request(); - $request->attributes->set('_route_params', ['schemaName' => 'myschema']); $collector->onPostExecutor(new ExecutorResultEvent( new ExecutionResult(['res' => 'ok', 'error' => 'my error']), - ExecutorArgumentsEvent::create(new ExtensibleSchema([]), 'invalid', new ArrayObject()) + ExecutorArgumentsEvent::create('test_schema', new ExtensibleSchema([]), 'invalid', new ArrayObject()) )); $collector->onPostExecutor(new ExecutorResultEvent( new ExecutionResult(['res' => 'ok', 'error' => 'my error']), - ExecutorArgumentsEvent::create(new ExtensibleSchema([]), 'query{ myalias: test{field1, field2} }', new ArrayObject(), null, ['variable1' => 'v1']) + ExecutorArgumentsEvent::create('test_schema', new ExtensibleSchema([]), 'query{ myalias: test{field1, field2} }', new ArrayObject(), null, ['variable1' => 'v1']) )); $collector->collect($request, new Response()); - $this->assertEquals($collector->getSchema(), 'myschema'); + $this->assertEquals($collector->getSchema(), 'test_schema'); $this->assertEquals($collector->getName(), 'graphql'); $this->assertEquals($collector->getCount(), 1); $this->assertTrue($collector->getError());