diff --git a/docs/annotations/annotations-reference.md b/docs/annotations/annotations-reference.md index 8f4a5feff..8dabff70b 100644 --- a/docs/annotations/annotations-reference.md +++ b/docs/annotations/annotations-reference.md @@ -381,12 +381,18 @@ class SecretArea { ## @Mutation This annotation applies on methods for classes tagged with the `@Provider` annotation. It indicates that the method on this class will resolve a Mutation field. -The resulting field is added to the root Mutation type (defined in configuration at key `overblog_graphql.definitions.schema.mutation`). +The corresponding GraphQL field is added to the GraphQL type(s) following the logic: +- The type(s) specified in the `targetTypes` attribute of the `@Mutation` annotation if it's defined. + or +- The type(s) specified in the `targetMutationTypes` attribute of the `@Provider` annotation if it's defined. + or +- The root Query type of the default schema (defined in configuration at key `overblog_graphql.definitions.schema.mutation` or `overblog_graphql.definitions.schema.default.mutation`). + The class exposing the mutation(s) must be declared as a [service](https://symfony.com/doc/current/service_container.html). Optional attributes: -- **targetType** : The GraphQL type(s) 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)). You can specify one or multiple target types. +- **targetTypes** : The GraphQL type(s) 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)). You can specify one or multiple target types. Example: @@ -426,17 +432,25 @@ You can use `@Access` and/or `@IsPublic` on a provider class to add default acce Optional attributes: -- **prefix** : A prefix to apply to all field names from this provider +- **prefix**: A prefix to apply to all field names from this provider +- **targetQueryTypes**: The default GraphQL type(s) to attach the provider `@Query` to +- **targetMutationTypes**: The default GraphQL type(s) to attach the provider `@Mutation` to ## @Query This annotation applies on methods for classes tagged with the `@Provider` annotation. It indicates that on this class a method will resolve a Query field. -By default, the resulting field is added to the root Query type (define in configuration at key `overblog_graphql.definitions.schema.query`). +The corresponding GraphQL field is added to the GraphQL type(s) following the logic: +- The type(s) specified in the `targetTypes` attribute of the `@Query` annotation if it's defined. + or +- The type(s) specified in the `targetQueryTypes` attribute of the `@Provider` annotation if it's defined. + or +- The root Query type of the default schema (defined in configuration at key `overblog_graphql.definitions.schema.query` or `overblog_graphql.definitions.schema.default.query`). + The class exposing the query(ies) must be declared as a [service](https://symfony.com/doc/current/service_container.html). Optional attributes: -- **targetType** : The GraphQL type(s) 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)). You can specify one or multiple target types. +- **targetTypes** : The GraphQL type(s) 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)). You can specify one or multiple target types. Example: diff --git a/src/Annotation/Mutation.php b/src/Annotation/Mutation.php index febd82040..f1dd2b040 100644 --- a/src/Annotation/Mutation.php +++ b/src/Annotation/Mutation.php @@ -12,10 +12,17 @@ */ final class Mutation extends Field { + /** + * @var array + * + * @deprecated This property is deprecated since 1.0 and will be removed in 1.1. Use $targetTypes instead. + */ + public array $targetType; + /** * The target types to attach this mutation to (useful when multiple schemas are allowed). * * @var array */ - public array $targetType; + public array $targetTypes; } diff --git a/src/Annotation/Provider.php b/src/Annotation/Provider.php index 388b20770..0b04438bf 100644 --- a/src/Annotation/Provider.php +++ b/src/Annotation/Provider.php @@ -14,8 +14,22 @@ final class Provider implements Annotation { /** * Optionnal prefix for provider fields. - * + * * @var string */ public string $prefix; + + /** + * The default target types to attach the provider queries to. + * + * @var array + */ + public array $targetQueryTypes; + + /** + * The default target types to attach the provider mutations to. + * + * @var array + */ + public array $targetMutationTypes; } diff --git a/src/Annotation/Query.php b/src/Annotation/Query.php index 993156c1c..bd698fef1 100644 --- a/src/Annotation/Query.php +++ b/src/Annotation/Query.php @@ -12,10 +12,17 @@ */ final class Query extends Field { + /** + * @var array + * + * @deprecated This property is deprecated since 1.0 and will be removed in 1.1. Use $targetTypes instead. + */ + public array $targetType; + /** * The target types to attach this query to. * * @var array */ - public array $targetType; + public array $targetTypes; } diff --git a/src/Config/Parser/AnnotationParser.php b/src/Config/Parser/AnnotationParser.php index 12deb80f4..8ca6a6901 100644 --- a/src/Config/Parser/AnnotationParser.php +++ b/src/Config/Parser/AnnotationParser.php @@ -710,7 +710,16 @@ private static function getGraphQLFieldsFromProviders(GraphClass $graphClass, st continue; } - $annotationTargets = $annotation->targetType ?? null; + // TODO: Remove old property check in 1.1 + $annotationTargets = $annotation->targetTypes ?? $annotation->targetType ?? null; + + if (null === $annotationTargets) { + if ($annotation instanceof GQL\Mutation && isset($providerAnnotation->targetMutationTypes)) { + $annotationTargets = $providerAnnotation->targetMutationTypes; + } elseif ($annotation instanceof GQL\Query && isset($providerAnnotation->targetQueryTypes)) { + $annotationTargets = $providerAnnotation->targetQueryTypes; + } + } if (null === $annotationTargets) { if ($isDefaultTarget) { @@ -728,7 +737,7 @@ private static function getGraphQLFieldsFromProviders(GraphClass $graphClass, st } if (!$annotation instanceof $expectedAnnotation) { - if (GQL\Mutation::class == $expectedAnnotation) { + if (GQL\Mutation::class === $expectedAnnotation) { $message = sprintf('The provider "%s" try to add a query field on type "%s" (through @Query on method "%s") but "%s" is a mutation.', $providerMetadata->getName(), $targetType, $method->getName(), $targetType); } else { $message = sprintf('The provider "%s" try to add a mutation on type "%s" (through @Mutation on method "%s") but "%s" is not a mutation.', $providerMetadata->getName(), $targetType, $method->getName(), $targetType); diff --git a/tests/Config/Parser/AnnotationParserTest.php b/tests/Config/Parser/AnnotationParserTest.php index 3585ebae0..3c391ecbe 100644 --- a/tests/Config/Parser/AnnotationParserTest.php +++ b/tests/Config/Parser/AnnotationParserTest.php @@ -276,6 +276,10 @@ public function testProviders(): void 'access' => '@=default_access', 'public' => '@=default_public', ], + 'countSecretWeapons' => [ + 'type' => 'Int!', + 'resolve' => "@=call(service('Overblog\\\\GraphQLBundle\\\\Tests\\\\Config\\\\Parser\\\\fixtures\\\\annotations\\\\Repository\\\\WeaponRepository').countSecretWeapons, arguments({}, args))", + ], ], ]); @@ -316,6 +320,10 @@ public function testProvidersMultischema(): void 'access' => '@=default_access', 'public' => '@=default_public', ], + 'hasSecretWeapons' => [ + 'type' => 'Boolean!', + 'resolve' => "@=call(service('Overblog\\\\GraphQLBundle\\\\Tests\\\\Config\\\\Parser\\\\fixtures\\\\annotations\\\\Repository\\\\WeaponRepository').hasSecretWeapons, arguments({}, args))", + ], ], ]); @@ -335,6 +343,10 @@ public function testProvidersMultischema(): void 'access' => '@=default_access', 'public' => '@=default_public', ], + 'createLightsaber' => [ + 'type' => 'Boolean!', + 'resolve' => "@=call(service('Overblog\\\\GraphQLBundle\\\\Tests\\\\Config\\\\Parser\\\\fixtures\\\\annotations\\\\Repository\\\\WeaponRepository').createLightsaber, arguments({}, args))", + ], ], ]); } diff --git a/tests/Config/Parser/fixtures/annotations/Repository/PlanetRepository.php b/tests/Config/Parser/fixtures/annotations/Repository/PlanetRepository.php index 562dce356..ccb5a2490 100644 --- a/tests/Config/Parser/fixtures/annotations/Repository/PlanetRepository.php +++ b/tests/Config/Parser/fixtures/annotations/Repository/PlanetRepository.php @@ -45,7 +45,7 @@ public function getAllowedPlanetsForDroids(): array } /** - * @GQL\Query(type="Planet", targetType="RootQuery2") + * @GQL\Query(type="Planet", targetTypes="RootQuery2") */ public function getPlanetSchema2(): ?Planet { @@ -53,7 +53,7 @@ public function getPlanetSchema2(): ?Planet } /** - * @GQL\Mutation(type="Planet", targetType="RootMutation2", args={ + * @GQL\Mutation(type="Planet", targetTypes="RootMutation2", args={ * @GQL\Arg(type="PlanetInput!", name="planetInput") * }) * @GQL\IsPublic("override_public") @@ -64,7 +64,7 @@ public function createPlanetSchema2(array $planetInput): array } /** - * @GQL\Mutation(targetType={"RootMutation", "RootMutation2"}) + * @GQL\Mutation(targetTypes={"RootMutation", "RootMutation2"}) */ public function destroyPlanet(int $planetId): bool { @@ -72,7 +72,7 @@ public function destroyPlanet(int $planetId): bool } /** - * @GQL\Query(targetType={"RootQuery", "RootQuery2"}) + * @GQL\Query(targetTypes={"RootQuery", "RootQuery2"}) */ public function isPlanetDestroyed(int $planetId): bool { @@ -80,7 +80,7 @@ public function isPlanetDestroyed(int $planetId): bool } /** - * @GQL\Query(targetType={"Droid", "Mandalorian"}, name="armorResistance") + * @GQL\Query(targetTypes={"Droid", "Mandalorian"}, name="armorResistance") */ public function getArmorResistance(): int { diff --git a/tests/Config/Parser/fixtures/annotations/Repository/WeaponRepository.php b/tests/Config/Parser/fixtures/annotations/Repository/WeaponRepository.php new file mode 100644 index 000000000..4a596fac2 --- /dev/null +++ b/tests/Config/Parser/fixtures/annotations/Repository/WeaponRepository.php @@ -0,0 +1,37 @@ +