Skip to content

Commit

Permalink
Simplify blog example TypeRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia authored Jun 18, 2024
1 parent b1d5956 commit a525e5b
Show file tree
Hide file tree
Showing 22 changed files with 130 additions and 271 deletions.
4 changes: 2 additions & 2 deletions examples/00-hello-world/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
4 changes: 2 additions & 2 deletions examples/00-hello-world/graphql.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
19 changes: 10 additions & 9 deletions examples/01-blog/Blog/Type/CommentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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),
],

Expand Down
9 changes: 5 additions & 4 deletions examples/01-blog/Blog/Type/Field/HtmlField.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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);
Expand Down
19 changes: 11 additions & 8 deletions examples/01-blog/Blog/Type/ImageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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');
},
Expand Down
11 changes: 6 additions & 5 deletions examples/01-blog/Blog/Type/NodeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -17,7 +18,7 @@ public function __construct()
parent::__construct([
'name' => 'Node',
'fields' => [
'id' => Types::id(),
'id' => Type::id(),
],
'resolveType' => [$this, 'resolveNodeType'],
]);
Expand All @@ -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);
Expand Down
20 changes: 10 additions & 10 deletions examples/01-blog/Blog/Type/QueryType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
],
Expand All @@ -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');
},
Expand Down
10 changes: 5 additions & 5 deletions examples/01-blog/Blog/Type/SearchResultType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
29 changes: 15 additions & 14 deletions examples/01-blog/Blog/Type/StoryType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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,
],
],
Expand All @@ -53,22 +54,22 @@ 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,
],
],
'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<int, string> $affordances */
$affordances = [];
Expand All @@ -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)],
]);
}
}
Loading

0 comments on commit a525e5b

Please sign in to comment.