Skip to content

Add attributes targetTypeQuery and targetTypeMutation on @Provider #749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions docs/annotations/annotations-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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:

Expand Down
9 changes: 8 additions & 1 deletion src/Annotation/Mutation.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
*/
final class Mutation extends Field
{
/**
* @var array<string>
*
* @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<string>
*/
public array $targetType;
public array $targetTypes;
}
16 changes: 15 additions & 1 deletion src/Annotation/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>
*/
public array $targetQueryTypes;

/**
* The default target types to attach the provider mutations to.
*
* @var array<string>
*/
public array $targetMutationTypes;
}
9 changes: 8 additions & 1 deletion src/Annotation/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
*/
final class Query extends Field
{
/**
* @var array<string>
*
* @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<string>
*/
public array $targetType;
public array $targetTypes;
}
13 changes: 11 additions & 2 deletions src/Config/Parser/AnnotationParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
12 changes: 12 additions & 0 deletions tests/Config/Parser/AnnotationParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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))",
],
],
]);

Expand Down Expand Up @@ -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))",
],
],
]);

Expand All @@ -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))",
],
],
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ public function getAllowedPlanetsForDroids(): array
}

/**
* @GQL\Query(type="Planet", targetType="RootQuery2")
* @GQL\Query(type="Planet", targetTypes="RootQuery2")
*/
public function getPlanetSchema2(): ?Planet
{
return null;
}

/**
* @GQL\Mutation(type="Planet", targetType="RootMutation2", args={
* @GQL\Mutation(type="Planet", targetTypes="RootMutation2", args={
* @GQL\Arg(type="PlanetInput!", name="planetInput")
* })
* @GQL\IsPublic("override_public")
Expand All @@ -64,23 +64,23 @@ public function createPlanetSchema2(array $planetInput): array
}

/**
* @GQL\Mutation(targetType={"RootMutation", "RootMutation2"})
* @GQL\Mutation(targetTypes={"RootMutation", "RootMutation2"})
*/
public function destroyPlanet(int $planetId): bool
{
return true;
}

/**
* @GQL\Query(targetType={"RootQuery", "RootQuery2"})
* @GQL\Query(targetTypes={"RootQuery", "RootQuery2"})
*/
public function isPlanetDestroyed(int $planetId): bool
{
return true;
}

/**
* @GQL\Query(targetType={"Droid", "Mandalorian"}, name="armorResistance")
* @GQL\Query(targetTypes={"Droid", "Mandalorian"}, name="armorResistance")
*/
public function getArmorResistance(): int
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Overblog\GraphQLBundle\Tests\Config\Parser\fixtures\annotations\Repository;

use Overblog\GraphQLBundle\Annotation as GQL;

/**
* @GQL\Provider(targetQueryTypes={"RootQuery2"}, targetMutationTypes="RootMutation2")
*/
class WeaponRepository
{
/**
* @GQL\Query
*/
public function hasSecretWeapons(): bool
{
return true;
}

/**
* @GQL\Query(targetTypes="RootQuery")
*/
public function countSecretWeapons(): int
{
return 2;
}

/**
* @GQL\Mutation
*/
public function createLightsaber(): bool
{
return true;
}
}