mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-25 22:36:02 +03:00
Updated blog example: demonstrated and commented inheritance vs composition options; added describing comments
This commit is contained in:
parent
19436c326d
commit
29670b378b
@ -7,7 +7,7 @@ use GraphQL\Utils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AppContext
|
* Class AppContext
|
||||||
* Instance available in all GraphQL resolvers
|
* Instance available in all GraphQL resolvers as 3rd argument
|
||||||
*
|
*
|
||||||
* @package GraphQL\Examples\Social
|
* @package GraphQL\Examples\Social
|
||||||
*/
|
*/
|
||||||
|
@ -4,8 +4,11 @@ namespace GraphQL\Examples\Blog\Type;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\DefinitionContainer;
|
use GraphQL\Type\DefinitionContainer;
|
||||||
|
|
||||||
class BaseType implements DefinitionContainer
|
abstract class BaseType implements DefinitionContainer
|
||||||
{
|
{
|
||||||
|
// Base class to reduce boilerplate for those who prefer own clean hierarchy of classes
|
||||||
|
// (and avoids extending GraphQL classes directly)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Type
|
* @var Type
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@ class CommentType extends BaseType
|
|||||||
{
|
{
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new ObjectType([
|
$this->definition = new ObjectType([
|
||||||
'name' => 'Comment',
|
'name' => 'Comment',
|
||||||
'fields' => function() use ($types) {
|
'fields' => function() use ($types) {
|
||||||
@ -18,6 +19,7 @@ class CommentType extends BaseType
|
|||||||
'id' => $types->id(),
|
'id' => $types->id(),
|
||||||
'author' => $types->user(),
|
'author' => $types->user(),
|
||||||
'parent' => $types->comment(),
|
'parent' => $types->comment(),
|
||||||
|
'isAnonymous' => $types->boolean(),
|
||||||
'replies' => [
|
'replies' => [
|
||||||
'type' => $types->listOf($types->comment()),
|
'type' => $types->listOf($types->comment()),
|
||||||
'args' => [
|
'args' => [
|
||||||
@ -45,6 +47,9 @@ class CommentType extends BaseType
|
|||||||
|
|
||||||
public function author(Comment $comment, $args, AppContext $context)
|
public function author(Comment $comment, $args, AppContext $context)
|
||||||
{
|
{
|
||||||
|
if ($comment->isAnonymous) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return $context->dataSource->findUser($comment->authorId);
|
return $context->dataSource->findUser($comment->authorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ class ContentFormatEnum extends BaseType
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
// Option #1: Define type using composition over inheritance, see ImageSizeEnumType for inheritance option
|
||||||
$this->definition = new EnumType([
|
$this->definition = new EnumType([
|
||||||
'name' => 'ContentFormatEnum',
|
'name' => 'ContentFormatEnum',
|
||||||
'values' => [self::FORMAT_TEXT, self::FORMAT_HTML]
|
'values' => [self::FORMAT_TEXT, self::FORMAT_HTML]
|
||||||
|
@ -2,24 +2,23 @@
|
|||||||
namespace GraphQL\Examples\Blog\Type\Enum;
|
namespace GraphQL\Examples\Blog\Type\Enum;
|
||||||
|
|
||||||
use GraphQL\Examples\Blog\Data\Image;
|
use GraphQL\Examples\Blog\Data\Image;
|
||||||
use GraphQL\Examples\Blog\Type\BaseType;
|
|
||||||
use GraphQL\Type\Definition\EnumType;
|
use GraphQL\Type\Definition\EnumType;
|
||||||
|
|
||||||
class ImageSizeEnumType extends BaseType
|
class ImageSizeEnumType extends EnumType
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* ImageSizeEnumType constructor.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->definition = new EnumType([
|
// Option #2: Define enum type using inheritance
|
||||||
'name' => 'ImageSizeEnum',
|
$config = [
|
||||||
|
// Note: 'name' option is not needed in this form - it will be inferred from className
|
||||||
'values' => [
|
'values' => [
|
||||||
'ICON' => Image::SIZE_ICON,
|
'ICON' => Image::SIZE_ICON,
|
||||||
'SMALL' => Image::SIZE_SMALL,
|
'SMALL' => Image::SIZE_SMALL,
|
||||||
'MEDIUM' => Image::SIZE_MEDIUM,
|
'MEDIUM' => Image::SIZE_MEDIUM,
|
||||||
'ORIGINAL' => Image::SIZE_ORIGINAL
|
'ORIGINAL' => Image::SIZE_ORIGINAL
|
||||||
]
|
]
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
parent::__construct($config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ class HtmlField
|
|||||||
{
|
{
|
||||||
$objectKey = $objectKey ?: $name;
|
$objectKey = $objectKey ?: $name;
|
||||||
|
|
||||||
|
// Demonstrates how to organize re-usable fields
|
||||||
|
// 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 [
|
return [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'type' => $types->string(),
|
'type' => $types->string(),
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace GraphQL\Examples\Blog\Type;
|
|
||||||
|
|
||||||
|
|
||||||
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
|
|
||||||
use GraphQL\Examples\Blog\TypeSystem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Field
|
|
||||||
* @package GraphQL\Examples\Blog\Type
|
|
||||||
*/
|
|
||||||
class FieldDefinitions
|
|
||||||
{
|
|
||||||
private $types;
|
|
||||||
|
|
||||||
public function __construct(TypeSystem $types)
|
|
||||||
{
|
|
||||||
$this->types = $types;
|
|
||||||
}
|
|
||||||
|
|
||||||
private $htmlField;
|
|
||||||
|
|
||||||
public function htmlField($name, $objectKey = null)
|
|
||||||
{
|
|
||||||
$objectKey = $objectKey ?: $name;
|
|
||||||
|
|
||||||
return $this->htmlField ?: $this->htmlField = [
|
|
||||||
'name' => $name,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,11 +7,12 @@ use GraphQL\Examples\Blog\TypeSystem;
|
|||||||
use GraphQL\Type\Definition\EnumType;
|
use GraphQL\Type\Definition\EnumType;
|
||||||
use GraphQL\Type\Definition\ObjectType;
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
|
||||||
class ImageType extends BaseType
|
class ImageType extends ObjectType
|
||||||
{
|
{
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
$this->definition = new ObjectType([
|
// Option #2: define type using inheritance, see any other object type for compositional example
|
||||||
|
$config = [
|
||||||
'name' => 'ImageType',
|
'name' => 'ImageType',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'id' => $types->id(),
|
'id' => $types->id(),
|
||||||
@ -43,7 +44,9 @@ class ImageType extends BaseType
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
parent::__construct($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resolveUrl(Image $value, $args, AppContext $context)
|
public function resolveUrl(Image $value, $args, AppContext $context)
|
||||||
|
@ -11,6 +11,7 @@ class MentionType extends BaseType
|
|||||||
{
|
{
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new UnionType([
|
$this->definition = new UnionType([
|
||||||
'name' => 'Mention',
|
'name' => 'Mention',
|
||||||
'types' => function() use ($types) {
|
'types' => function() use ($types) {
|
||||||
|
@ -9,12 +9,9 @@ use GraphQL\Type\Definition\InterfaceType;
|
|||||||
|
|
||||||
class NodeType extends BaseType
|
class NodeType extends BaseType
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* NodeType constructor.
|
|
||||||
* @param TypeSystem $types
|
|
||||||
*/
|
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new InterfaceType([
|
$this->definition = new InterfaceType([
|
||||||
'name' => 'Node',
|
'name' => 'Node',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
|
@ -11,6 +11,7 @@ class QueryType extends BaseType
|
|||||||
{
|
{
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new ObjectType([
|
$this->definition = new ObjectType([
|
||||||
'name' => 'Query',
|
'name' => 'Query',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
|
@ -10,6 +10,7 @@ class EmailType extends BaseType
|
|||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
// Option #1: define scalar types using composition (see UrlType fo option #2 using inheritance)
|
||||||
$this->definition = new CustomScalarType([
|
$this->definition = new CustomScalarType([
|
||||||
'name' => 'Email',
|
'name' => 'Email',
|
||||||
'serialize' => [$this, 'serialize'],
|
'serialize' => [$this, 'serialize'],
|
||||||
|
@ -5,14 +5,9 @@ use GraphQL\Language\AST\StringValue;
|
|||||||
use GraphQL\Type\Definition\ScalarType;
|
use GraphQL\Type\Definition\ScalarType;
|
||||||
use GraphQL\Utils;
|
use GraphQL\Utils;
|
||||||
|
|
||||||
/**
|
class UrlType extends ScalarType
|
||||||
* Class UrlTypeDefinition
|
|
||||||
*
|
|
||||||
* @package GraphQL\Examples\Blog\Type\Scalar
|
|
||||||
*/
|
|
||||||
class UrlTypeDefinition extends ScalarType
|
|
||||||
{
|
{
|
||||||
public $name = 'Url';
|
// Option #2: Displays scalar type defined using inheritance. See EmailType for definition via composition
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes an internal value to include in a response.
|
* Serializes an internal value to include in a response.
|
@ -23,6 +23,7 @@ class StoryType extends BaseType
|
|||||||
|
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new ObjectType([
|
$this->definition = new ObjectType([
|
||||||
'name' => 'Story',
|
'name' => 'Story',
|
||||||
'fields' => function() use ($types) {
|
'fields' => function() use ($types) {
|
||||||
|
@ -11,6 +11,7 @@ class UserType extends BaseType
|
|||||||
{
|
{
|
||||||
public function __construct(TypeSystem $types)
|
public function __construct(TypeSystem $types)
|
||||||
{
|
{
|
||||||
|
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
|
||||||
$this->definition = new ObjectType([
|
$this->definition = new ObjectType([
|
||||||
'name' => 'User',
|
'name' => 'User',
|
||||||
'fields' => function() use ($types) {
|
'fields' => function() use ($types) {
|
||||||
|
@ -5,13 +5,12 @@ use GraphQL\Examples\Blog\Type\CommentType;
|
|||||||
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
|
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
|
||||||
use GraphQL\Examples\Blog\Type\Enum\ImageSizeEnumType;
|
use GraphQL\Examples\Blog\Type\Enum\ImageSizeEnumType;
|
||||||
use GraphQL\Examples\Blog\Type\Field\HtmlField;
|
use GraphQL\Examples\Blog\Type\Field\HtmlField;
|
||||||
use GraphQL\Examples\Blog\Type\FieldDefinitions;
|
|
||||||
use GraphQL\Examples\Blog\Type\MentionType;
|
use GraphQL\Examples\Blog\Type\MentionType;
|
||||||
use GraphQL\Examples\Blog\Type\NodeType;
|
use GraphQL\Examples\Blog\Type\NodeType;
|
||||||
use GraphQL\Examples\Blog\Type\QueryType;
|
use GraphQL\Examples\Blog\Type\QueryType;
|
||||||
use GraphQL\Examples\Blog\Type\Scalar\EmailType;
|
use GraphQL\Examples\Blog\Type\Scalar\EmailType;
|
||||||
use GraphQL\Examples\Blog\Type\StoryType;
|
use GraphQL\Examples\Blog\Type\StoryType;
|
||||||
use GraphQL\Examples\Blog\Type\Scalar\UrlTypeDefinition;
|
use GraphQL\Examples\Blog\Type\Scalar\UrlType;
|
||||||
use GraphQL\Examples\Blog\Type\UserType;
|
use GraphQL\Examples\Blog\Type\UserType;
|
||||||
use GraphQL\Examples\Blog\Type\ImageType;
|
use GraphQL\Examples\Blog\Type\ImageType;
|
||||||
use GraphQL\Type\Definition\ListOfType;
|
use GraphQL\Type\Definition\ListOfType;
|
||||||
@ -129,15 +128,15 @@ class TypeSystem
|
|||||||
|
|
||||||
public function email()
|
public function email()
|
||||||
{
|
{
|
||||||
return $this->emailType ?: ($this->emailType = new EmailType);
|
return $this->emailType ?: ($this->emailType = new EmailType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return UrlTypeDefinition
|
* @return UrlType
|
||||||
*/
|
*/
|
||||||
public function url()
|
public function url()
|
||||||
{
|
{
|
||||||
return $this->urlType ?: ($this->urlType = new UrlTypeDefinition);
|
return $this->urlType ?: ($this->urlType = new UrlType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user