From a525e5bff0b8d19b74abeca32f302b6bb18dc7cf Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Tue, 18 Jun 2024 10:40:07 +0200 Subject: [PATCH] Simplify blog example TypeRegistry --- examples/00-hello-world/README.md | 4 +- examples/00-hello-world/graphql.php | 4 +- examples/01-blog/Blog/Type/CommentType.php | 19 +- .../01-blog/Blog/Type/Field/HtmlField.php | 9 +- examples/01-blog/Blog/Type/ImageType.php | 19 +- examples/01-blog/Blog/Type/NodeType.php | 11 +- examples/01-blog/Blog/Type/QueryType.php | 20 +- .../01-blog/Blog/Type/SearchResultType.php | 10 +- examples/01-blog/Blog/Type/StoryType.php | 29 +-- examples/01-blog/Blog/Type/UserType.php | 23 ++- examples/01-blog/Blog/TypeRegistry.php | 31 +++ examples/01-blog/Blog/Types.php | 178 ------------------ examples/01-blog/README.md | 4 +- examples/01-blog/graphql.php | 7 +- .../02-schema-definition-language/README.md | 4 +- .../02-schema-definition-language/graphql.php | 4 +- examples/03-standard-server/README.md | 4 +- examples/03-standard-server/graphql.php | 4 +- .../04-async-php/amphp/event-loop/graphql.php | 2 +- .../amphp/http-server/graphql.php | 2 +- .../hello-world-http-server/graphql.php | 4 +- tests/Type/InputObjectTypeTest.php | 9 +- 22 files changed, 130 insertions(+), 271 deletions(-) create mode 100644 examples/01-blog/Blog/TypeRegistry.php delete mode 100644 examples/01-blog/Blog/Types.php diff --git a/examples/00-hello-world/README.md b/examples/00-hello-world/README.md index 053a04268..59fcf5e6f 100644 --- a/examples/00-hello-world/README.md +++ b/examples/00-hello-world/README.md @@ -12,11 +12,11 @@ php -S localhost:8080 graphql.php ### Try query ``` -curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 ``` ### Try mutation ``` -curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 ``` diff --git a/examples/00-hello-world/graphql.php b/examples/00-hello-world/graphql.php index be6c01dfa..953571f22 100644 --- a/examples/00-hello-world/graphql.php +++ b/examples/00-hello-world/graphql.php @@ -4,10 +4,10 @@ // php -S localhost:8080 graphql.php // Try query -// curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 // Try mutation -// curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 require_once __DIR__ . '/../../vendor/autoload.php'; diff --git a/examples/01-blog/Blog/Type/CommentType.php b/examples/01-blog/Blog/Type/CommentType.php index 77dac01b1..89c3335ad 100644 --- a/examples/01-blog/Blog/Type/CommentType.php +++ b/examples/01-blog/Blog/Type/CommentType.php @@ -6,9 +6,10 @@ use GraphQL\Examples\Blog\Data\DataSource; use GraphQL\Examples\Blog\Data\User; use GraphQL\Examples\Blog\Type\Field\HtmlField; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\ObjectType; +use GraphQL\Type\Definition\Type; class CommentType extends ObjectType { @@ -17,33 +18,33 @@ public function __construct() parent::__construct([ 'name' => 'Comment', 'fields' => static fn (): array => [ - 'id' => Types::id(), + 'id' => Type::id(), 'author' => [ - 'type' => Types::user(), + 'type' => TypeRegistry::type(UserType::class), 'resolve' => static fn (Comment $comment): ?User => $comment->isAnonymous ? null : DataSource::findUser($comment->authorId), ], 'parent' => [ - 'type' => Types::comment(), + 'type' => TypeRegistry::type(CommentType::class), 'resolve' => static fn (Comment $comment): ?Comment => $comment->parentId !== null ? DataSource::findComment($comment->parentId) : null, ], - 'isAnonymous' => Types::boolean(), + 'isAnonymous' => Type::boolean(), 'replies' => [ - 'type' => new ListOfType(Types::comment()), + 'type' => new ListOfType(TypeRegistry::type(CommentType::class)), 'args' => [ - 'after' => Types::int(), + 'after' => Type::int(), 'limit' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'defaultValue' => 5, ], ], 'resolve' => fn (Comment $comment, array $args): array => DataSource::findReplies($comment->id, $args['limit'], $args['after'] ?? null), ], 'totalReplyCount' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'resolve' => static fn (Comment $comment): int => DataSource::countReplies($comment->id), ], diff --git a/examples/01-blog/Blog/Type/Field/HtmlField.php b/examples/01-blog/Blog/Type/Field/HtmlField.php index 871c1b775..5dd92c4be 100644 --- a/examples/01-blog/Blog/Type/Field/HtmlField.php +++ b/examples/01-blog/Blog/Type/Field/HtmlField.php @@ -4,7 +4,8 @@ use GraphQL\Error\InvariantViolation; use GraphQL\Examples\Blog\Type\Enum\ContentFormatType; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; +use GraphQL\Type\Definition\Type; class HtmlField { @@ -25,13 +26,13 @@ public static function build(array $config): array // Usual example: when the same field with same args shows up in different types // (for example when it is a part of some interface) return [ - 'type' => Types::string(), + 'type' => Type::string(), 'args' => [ 'format' => [ - 'type' => Types::contentFormat(), + 'type' => TypeRegistry::type(ContentFormatType::class), 'defaultValue' => ContentFormatType::FORMAT_HTML, ], - 'maxLength' => Types::int(), + 'maxLength' => Type::int(), ], 'resolve' => static function ($rootValue, array $args) use ($resolver): ?string { $html = $resolver($rootValue, $args); diff --git a/examples/01-blog/Blog/Type/ImageType.php b/examples/01-blog/Blog/Type/ImageType.php index 1b41e69ce..4497d0d41 100644 --- a/examples/01-blog/Blog/Type/ImageType.php +++ b/examples/01-blog/Blog/Type/ImageType.php @@ -4,10 +4,13 @@ use GraphQL\Examples\Blog\AppContext; use GraphQL\Examples\Blog\Data\Image; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\Type\Enum\ImageSizeType; +use GraphQL\Examples\Blog\Type\Scalar\UrlType; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ResolveInfo; +use GraphQL\Type\Definition\Type; class ImageType extends ObjectType { @@ -16,24 +19,24 @@ public function __construct() parent::__construct([ 'name' => 'Image', 'fields' => [ - 'id' => Types::id(), - 'size' => Types::imageSize(), - 'width' => Types::int(), - 'height' => Types::int(), + 'id' => Type::id(), + 'size' => TypeRegistry::type(ImageSizeType::class), + 'width' => Type::int(), + 'height' => Type::int(), 'url' => [ - 'type' => Types::url(), + 'type' => TypeRegistry::type(UrlType::class), 'resolve' => [$this, 'resolveUrl'], ], // Just for the sake of example 'fieldWithError' => [ - 'type' => Types::string(), + 'type' => Type::string(), 'resolve' => static function (): void { throw new \Exception('Field with exception'); }, ], 'nonNullFieldWithError' => [ - 'type' => new NonNull(Types::string()), + 'type' => new NonNull(Type::string()), 'resolve' => static function (): void { throw new \Exception('Non-null field with exception'); }, diff --git a/examples/01-blog/Blog/Type/NodeType.php b/examples/01-blog/Blog/Type/NodeType.php index 0776871a3..548cce1e8 100644 --- a/examples/01-blog/Blog/Type/NodeType.php +++ b/examples/01-blog/Blog/Type/NodeType.php @@ -5,9 +5,10 @@ use GraphQL\Examples\Blog\Data\Image; use GraphQL\Examples\Blog\Data\Story; use GraphQL\Examples\Blog\Data\User; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; +use GraphQL\Type\Definition\Type; use GraphQL\Utils\Utils; class NodeType extends InterfaceType @@ -17,7 +18,7 @@ public function __construct() parent::__construct([ 'name' => 'Node', 'fields' => [ - 'id' => Types::id(), + 'id' => Type::id(), ], 'resolveType' => [$this, 'resolveNodeType'], ]); @@ -33,15 +34,15 @@ public function __construct() public function resolveNodeType($object) { if ($object instanceof User) { - return Types::user(); + return TypeRegistry::type(UserType::class); } if ($object instanceof Image) { - return Types::image(); + return TypeRegistry::type(ImageType::class); } if ($object instanceof Story) { - return Types::story(); + return TypeRegistry::type(StoryType::class); } $notNode = Utils::printSafe($object); diff --git a/examples/01-blog/Blog/Type/QueryType.php b/examples/01-blog/Blog/Type/QueryType.php index d1d1df05b..dde14d006 100644 --- a/examples/01-blog/Blog/Type/QueryType.php +++ b/examples/01-blog/Blog/Type/QueryType.php @@ -5,7 +5,7 @@ use GraphQL\Examples\Blog\Data\DataSource; use GraphQL\Examples\Blog\Data\Story; use GraphQL\Examples\Blog\Data\User; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; @@ -19,27 +19,27 @@ public function __construct() 'name' => 'Query', 'fields' => [ 'user' => [ - 'type' => Types::user(), + 'type' => TypeRegistry::type(UserType::class), 'description' => 'Returns user by id (in range of 1-5)', 'args' => [ - 'id' => new NonNull(Types::id()), + 'id' => new NonNull(Type::id()), ], 'resolve' => static fn ($rootValue, array $args): ?User => DataSource::findUser((int) $args['id']), ], 'viewer' => [ - 'type' => Types::user(), + 'type' => TypeRegistry::type(UserType::class), 'description' => 'Represents currently logged-in user (for the sake of example - simply returns user with id == 1)', ], 'stories' => [ - 'type' => new ListOfType(Types::story()), + 'type' => new ListOfType(TypeRegistry::type(StoryType::class)), 'description' => 'Returns subset of stories posted for this blog', 'args' => [ 'after' => [ - 'type' => Types::id(), + 'type' => Type::id(), 'description' => 'Fetch stories listed after the story with this ID', ], 'limit' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'description' => 'Number of stories to be returned', 'defaultValue' => 10, ], @@ -52,17 +52,17 @@ public function __construct() ), ], 'lastStoryPosted' => [ - 'type' => Types::story(), + 'type' => TypeRegistry::type(StoryType::class), 'description' => 'Returns last story posted for this blog', 'resolve' => static fn (): ?Story => DataSource::findLatestStory(), ], 'deprecatedField' => [ - 'type' => Types::string(), + 'type' => Type::string(), 'deprecationReason' => 'This field is deprecated!', 'resolve' => static fn (): string => 'You can request deprecated field, but it is not displayed in auto-generated documentation by default.', ], 'fieldWithException' => [ - 'type' => Types::string(), + 'type' => Type::string(), 'resolve' => static function (): void { throw new \Exception('Exception message thrown in field resolver'); }, diff --git a/examples/01-blog/Blog/Type/SearchResultType.php b/examples/01-blog/Blog/Type/SearchResultType.php index 03bd32ae0..12db42c84 100644 --- a/examples/01-blog/Blog/Type/SearchResultType.php +++ b/examples/01-blog/Blog/Type/SearchResultType.php @@ -4,7 +4,7 @@ use GraphQL\Examples\Blog\Data\Story; use GraphQL\Examples\Blog\Data\User; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\UnionType; class SearchResultType extends UnionType @@ -14,16 +14,16 @@ public function __construct() parent::__construct([ 'name' => 'SearchResult', 'types' => static fn (): array => [ - Types::story(), - Types::user(), + TypeRegistry::type(StoryType::class), + TypeRegistry::type(UserType::class), ], 'resolveType' => static function (object $value): callable { if ($value instanceof Story) { - return Types::story(); + return TypeRegistry::type(StoryType::class); } if ($value instanceof User) { - return Types::user(); + return TypeRegistry::type(UserType::class); } $unknownType = \get_class($value); diff --git a/examples/01-blog/Blog/Type/StoryType.php b/examples/01-blog/Blog/Type/StoryType.php index 5e3973bd4..157505594 100644 --- a/examples/01-blog/Blog/Type/StoryType.php +++ b/examples/01-blog/Blog/Type/StoryType.php @@ -8,9 +8,10 @@ use GraphQL\Examples\Blog\Data\User; use GraphQL\Examples\Blog\Type\Enum\StoryAffordancesType; use GraphQL\Examples\Blog\Type\Field\HtmlField; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\ObjectType; +use GraphQL\Type\Definition\Type; class StoryType extends ObjectType { @@ -19,28 +20,28 @@ public function __construct() parent::__construct([ 'name' => 'Story', 'fields' => static fn (): array => [ - 'id' => Types::id(), + 'id' => Type::id(), 'author' => [ - 'type' => Types::user(), + 'type' => TypeRegistry::type(UserType::class), 'resolve' => static fn (Story $story): ?User => DataSource::findUser($story->authorId), ], 'mentions' => [ - 'type' => new ListOfType(Types::mention()), + 'type' => new ListOfType(TypeRegistry::type(SearchResultType::class)), 'resolve' => static fn (Story $story): array => DataSource::findStoryMentions($story->id), ], 'totalCommentCount' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'resolve' => static fn (Story $story): int => DataSource::countComments($story->id), ], 'comments' => [ - 'type' => new ListOfType(Types::comment()), + 'type' => new ListOfType(TypeRegistry::type(CommentType::class)), 'args' => [ 'after' => [ - 'type' => Types::id(), + 'type' => Type::id(), 'description' => 'Load all comments listed after given comment ID', ], 'limit' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'defaultValue' => 5, ], ], @@ -53,10 +54,10 @@ public function __construct() ), ], 'likes' => [ - 'type' => new ListOfType(Types::user()), + 'type' => new ListOfType(TypeRegistry::type(UserType::class)), 'args' => [ 'limit' => [ - 'type' => Types::int(), + 'type' => Type::int(), 'description' => 'Limit the number of recent likes returned', 'defaultValue' => 5, ], @@ -64,11 +65,11 @@ public function __construct() 'resolve' => static fn (Story $story): array => DataSource::findLikes($story->id, 10), ], 'likedBy' => [ - 'type' => new ListOfType(Types::user()), + 'type' => new ListOfType(TypeRegistry::type(UserType::class)), 'resolve' => static fn (Story $story) => DataSource::findLikes($story->id, 10), ], 'affordances' => [ - 'type' => new ListOfType(Types::storyAffordances()), + 'type' => new ListOfType(TypeRegistry::type(StoryAffordancesType::class)), 'resolve' => function (Story $story, array $args, AppContext $context): array { /** @var array $affordances */ $affordances = []; @@ -88,14 +89,14 @@ public function __construct() }, ], 'hasViewerLiked' => [ - 'type' => Types::boolean(), + 'type' => Type::boolean(), 'resolve' => static fn (Story $story, array $args, AppContext $context): bool => DataSource::isLikedBy($story->id, $context->viewer->id), ], 'body' => HtmlField::build([ 'resolve' => static fn (Story $story): string => $story->body, ]), ], - 'interfaces' => [Types::node()], + 'interfaces' => [TypeRegistry::type(NodeType::class)], ]); } } diff --git a/examples/01-blog/Blog/Type/UserType.php b/examples/01-blog/Blog/Type/UserType.php index f8755723a..3cd59f8fb 100644 --- a/examples/01-blog/Blog/Type/UserType.php +++ b/examples/01-blog/Blog/Type/UserType.php @@ -6,9 +6,12 @@ use GraphQL\Examples\Blog\Data\Image; use GraphQL\Examples\Blog\Data\Story; use GraphQL\Examples\Blog\Data\User; -use GraphQL\Examples\Blog\Types; +use GraphQL\Examples\Blog\Type\Enum\ImageSizeType; +use GraphQL\Examples\Blog\Type\Scalar\EmailType; +use GraphQL\Examples\Blog\TypeRegistry; use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; +use GraphQL\Type\Definition\Type; class UserType extends ObjectType { @@ -18,30 +21,30 @@ public function __construct() 'name' => 'User', 'description' => 'Our blog authors', 'fields' => static fn (): array => [ - 'id' => Types::id(), - 'email' => Types::email(), + 'id' => Type::id(), + 'email' => TypeRegistry::type(EmailType::class), 'photo' => [ - 'type' => Types::image(), + 'type' => TypeRegistry::type(ImageType::class), 'description' => 'User photo URL', 'args' => [ - 'size' => new NonNull(Types::imageSize()), + 'size' => new NonNull(TypeRegistry::type(ImageSizeType::class)), ], 'resolve' => static fn (User $user, array $args): Image => DataSource::getUserPhoto($user->id, $args['size']), ], - 'firstName' => Types::string(), - 'lastName' => Types::string(), + 'firstName' => Type::string(), + 'lastName' => Type::string(), 'lastStoryPosted' => [ - 'type' => Types::story(), + 'type' => TypeRegistry::type(StoryType::class), 'resolve' => static fn (User $user): ?Story => DataSource::findLastStoryFor($user->id), ], 'fieldWithError' => [ - 'type' => Types::string(), + 'type' => Type::string(), 'resolve' => static function (): void { throw new \Exception('This is error field'); }, ], ], - 'interfaces' => [Types::node()], + 'interfaces' => [TypeRegistry::type(NodeType::class)], ]); } } diff --git a/examples/01-blog/Blog/TypeRegistry.php b/examples/01-blog/Blog/TypeRegistry.php new file mode 100644 index 000000000..ff68ffb22 --- /dev/null +++ b/examples/01-blog/Blog/TypeRegistry.php @@ -0,0 +1,31 @@ +, Type&NamedType> */ + private static array $types = []; + + /** + * Returns a lazily resolved singleton of the given type class. + * + * @template T of Type&NamedType + * + * @param class-string $classname + * + * @return \Closure(): T + */ + public static function type(string $classname): \Closure + { + // @phpstan-ignore-next-line generic type matches + return static fn () => self::$types[$classname] ??= new $classname(); + } +} diff --git a/examples/01-blog/Blog/Types.php b/examples/01-blog/Blog/Types.php deleted file mode 100644 index d1c108458..000000000 --- a/examples/01-blog/Blog/Types.php +++ /dev/null @@ -1,178 +0,0 @@ - */ - private static array $types = []; - - /** - * @throws \Exception - * - * @return Type&NamedType - */ - public static function load(string $typeName): Type - { - if (isset(self::$types[$typeName])) { - return self::$types[$typeName]; - } - - // For every type, this class must define a method with the same name - // but the first letter is in lower case. - switch ($typeName) { - case 'ID': - $methodName = 'id'; - break; - default: - $methodName = \lcfirst($typeName); - } - if (! method_exists(self::class, $methodName)) { - throw new \Exception("Unknown GraphQL type: {$typeName}."); - } - - $type = self::{$methodName}(); // @phpstan-ignore-line variable static method call - if (is_callable($type)) { - $type = $type(); - } - - return self::$types[$typeName] = $type; - } - - /** - * @param class-string $className - * - * @return Type&NamedType - */ - private static function byClassName(string $className): Type - { - $classNameParts = \explode('\\', $className); - $baseClassName = end($classNameParts); - // All type classes must use the suffix Type. - // This prevents name collisions between types and PHP keywords. - $typeName = \preg_replace('~Type$~', '', $baseClassName); - assert(is_string($typeName), 'regex is statically known to be correct'); - - // Type loading is very similar to PHP class loading, but keep in mind - // that the **typeLoader** must always return the same instance of a type. - // We can enforce that in our type registry by caching known types. - return self::$types[$typeName] ??= new $className(); - } - - /** - * @param class-string $classname - * - * @return \Closure(): (Type&NamedType) - */ - private static function lazyByClassName(string $classname): \Closure - { - return static fn () => self::byClassName($classname); - } - - /** @throws InvariantViolation */ - public static function boolean(): ScalarType - { - return Type::boolean(); - } - - /** @throws InvariantViolation */ - public static function float(): ScalarType - { - return Type::float(); - } - - /** @throws InvariantViolation */ - public static function id(): ScalarType - { - return Type::id(); - } - - /** @throws InvariantViolation */ - public static function int(): ScalarType - { - return Type::int(); - } - - /** @throws InvariantViolation */ - public static function string(): ScalarType - { - return Type::string(); - } - - public static function user(): callable - { - return self::lazyByClassName(UserType::class); - } - - public static function story(): callable - { - return self::lazyByClassName(StoryType::class); - } - - public static function comment(): callable - { - return self::lazyByClassName(CommentType::class); - } - - public static function image(): callable - { - return self::lazyByClassName(ImageType::class); - } - - public static function node(): callable - { - return self::lazyByClassName(NodeType::class); - } - - public static function mention(): callable - { - return self::lazyByClassName(SearchResultType::class); - } - - public static function imageSize(): callable - { - return self::lazyByClassName(ImageSizeType::class); - } - - public static function contentFormat(): callable - { - return self::lazyByClassName(ContentFormatType::class); - } - - public static function storyAffordances(): callable - { - return self::lazyByClassName(StoryAffordancesType::class); - } - - public static function email(): callable - { - return self::lazyByClassName(EmailType::class); - } - - public static function url(): callable - { - return self::lazyByClassName(UrlType::class); - } -} diff --git a/examples/01-blog/README.md b/examples/01-blog/README.md index 90f04b239..c63392f95 100644 --- a/examples/01-blog/README.md +++ b/examples/01-blog/README.md @@ -12,7 +12,7 @@ php -S localhost:8080 graphql.php ### Try query ``` -curl -d '{"query": "query { hello }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "query { hello }" }' --header "Content-Type: application/json" http://localhost:8080 ``` The response should be: @@ -95,7 +95,7 @@ fragment CommentView on Comment { Use autocomplete (via CTRL+space) to easily create your own query. -Note: GraphQL query requires at least one field per object type (to prevent accidental overfetching). +Note: GraphQL query requires at least one field per object type (to prevent accidental over-fetching). For example, the following query is invalid in GraphQL: ```graphql diff --git a/examples/01-blog/graphql.php b/examples/01-blog/graphql.php index 09204a659..c8385fbf7 100644 --- a/examples/01-blog/graphql.php +++ b/examples/01-blog/graphql.php @@ -4,16 +4,14 @@ // php -S localhost:8080 graphql.php // Try query -// curl -d '{"query": "query { hello }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "query { hello }" }' --header "Content-Type: application/json" http://localhost:8080 require_once __DIR__ . '/../../vendor/autoload.php'; use GraphQL\Examples\Blog\AppContext; use GraphQL\Examples\Blog\Data\DataSource; use GraphQL\Examples\Blog\Type\QueryType; -use GraphQL\Examples\Blog\Types; use GraphQL\Server\StandardServer; -use GraphQL\Type\Definition\Type; use GraphQL\Type\Schema; use GraphQL\Type\SchemaConfig; @@ -24,8 +22,7 @@ // https://webonyx.github.io/graphql-php/schema-definition/#configuration-options $schema = new Schema( (new SchemaConfig()) - ->setQuery(new QueryType()) - ->setTypeLoader([Types::class, 'load']) + ->setQuery(new QueryType()) ); // Prepare context that will be available in all field resolvers (as 3rd argument): diff --git a/examples/02-schema-definition-language/README.md b/examples/02-schema-definition-language/README.md index a6892cd69..3100d2b4c 100644 --- a/examples/02-schema-definition-language/README.md +++ b/examples/02-schema-definition-language/README.md @@ -12,11 +12,11 @@ php -S localhost:8080 graphql.php ### Try query ``` -curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 ``` ### Try mutation ``` -curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 ``` diff --git a/examples/02-schema-definition-language/graphql.php b/examples/02-schema-definition-language/graphql.php index 0c78290cc..4f8bb16b1 100644 --- a/examples/02-schema-definition-language/graphql.php +++ b/examples/02-schema-definition-language/graphql.php @@ -4,10 +4,10 @@ // php -S localhost:8080 graphql.php // Try query -// curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 // Try mutation -// curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 require_once __DIR__ . '/../../vendor/autoload.php'; diff --git a/examples/03-standard-server/README.md b/examples/03-standard-server/README.md index f07510146..8c09f72b6 100644 --- a/examples/03-standard-server/README.md +++ b/examples/03-standard-server/README.md @@ -12,11 +12,11 @@ php -S localhost:8080 graphql.php ### Try query ``` -curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 ``` ### Try mutation ``` -curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 ``` diff --git a/examples/03-standard-server/graphql.php b/examples/03-standard-server/graphql.php index 4eadc586b..12aaff40d 100644 --- a/examples/03-standard-server/graphql.php +++ b/examples/03-standard-server/graphql.php @@ -4,10 +4,10 @@ // php -S localhost:8080 graphql.php // Try query -// curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "query { echo(message: \"Hello World\") }" }' --header "Content-Type: application/json" http://localhost:8080 // Try mutation -// curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080 +// curl --data '{"query": "mutation { sum(x: 2, y: 2) }" }' --header "Content-Type: application/json" http://localhost:8080 require_once __DIR__ . '/../../vendor/autoload.php'; diff --git a/examples/04-async-php/amphp/event-loop/graphql.php b/examples/04-async-php/amphp/event-loop/graphql.php index 42c8403f6..cc2b0acf4 100644 --- a/examples/04-async-php/amphp/event-loop/graphql.php +++ b/examples/04-async-php/amphp/event-loop/graphql.php @@ -1,7 +1,7 @@ 'Mutation', 'fields' => [ 'action' => [ - 'type' => Types::boolean(), + 'type' => Type::boolean(), 'args' => [ 'input' => [ 'type' => $input, @@ -193,7 +192,7 @@ public function testParseValueFromLiterals(): void 'name' => 'Mutation', 'fields' => [ 'action' => [ - 'type' => Types::boolean(), + 'type' => Type::boolean(), 'args' => [ 'input' => [ 'type' => $input, @@ -267,7 +266,7 @@ public function testParseValueFromVariablesAndLiterals(): void 'name' => 'Mutation', 'fields' => [ 'action' => [ - 'type' => Types::boolean(), + 'type' => Type::boolean(), 'args' => [ 'input' => [ 'type' => $input, @@ -339,7 +338,7 @@ public function testParseValueNotCalledWhenNull(): void 'name' => 'Mutation', 'fields' => [ 'action' => [ - 'type' => Types::boolean(), + 'type' => Type::boolean(), 'args' => [ 'input' => [ 'type' => $input,