Updated blog example: demonstrated and commented inheritance vs composition options; added describing comments

This commit is contained in:
vladar 2016-10-24 17:07:52 +07:00
parent 19436c326d
commit 29670b378b
16 changed files with 39 additions and 60 deletions

View File

@ -7,7 +7,7 @@ use GraphQL\Utils;
/**
* Class AppContext
* Instance available in all GraphQL resolvers
* Instance available in all GraphQL resolvers as 3rd argument
*
* @package GraphQL\Examples\Social
*/

View File

@ -4,8 +4,11 @@ namespace GraphQL\Examples\Blog\Type;
use GraphQL\Type\Definition\Type;
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
*/

View File

@ -11,6 +11,7 @@ class CommentType extends BaseType
{
public function __construct(TypeSystem $types)
{
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
$this->definition = new ObjectType([
'name' => 'Comment',
'fields' => function() use ($types) {
@ -18,6 +19,7 @@ class CommentType extends BaseType
'id' => $types->id(),
'author' => $types->user(),
'parent' => $types->comment(),
'isAnonymous' => $types->boolean(),
'replies' => [
'type' => $types->listOf($types->comment()),
'args' => [
@ -45,6 +47,9 @@ class CommentType extends BaseType
public function author(Comment $comment, $args, AppContext $context)
{
if ($comment->isAnonymous) {
return null;
}
return $context->dataSource->findUser($comment->authorId);
}

View File

@ -11,6 +11,7 @@ class ContentFormatEnum extends BaseType
public function __construct()
{
// Option #1: Define type using composition over inheritance, see ImageSizeEnumType for inheritance option
$this->definition = new EnumType([
'name' => 'ContentFormatEnum',
'values' => [self::FORMAT_TEXT, self::FORMAT_HTML]

View File

@ -2,24 +2,23 @@
namespace GraphQL\Examples\Blog\Type\Enum;
use GraphQL\Examples\Blog\Data\Image;
use GraphQL\Examples\Blog\Type\BaseType;
use GraphQL\Type\Definition\EnumType;
class ImageSizeEnumType extends BaseType
class ImageSizeEnumType extends EnumType
{
/**
* ImageSizeEnumType constructor.
*/
public function __construct()
{
$this->definition = new EnumType([
'name' => 'ImageSizeEnum',
// Option #2: Define enum type using inheritance
$config = [
// Note: 'name' option is not needed in this form - it will be inferred from className
'values' => [
'ICON' => Image::SIZE_ICON,
'SMALL' => Image::SIZE_SMALL,
'MEDIUM' => Image::SIZE_MEDIUM,
'ORIGINAL' => Image::SIZE_ORIGINAL
]
]);
];
parent::__construct($config);
}
}

View File

@ -10,6 +10,9 @@ class HtmlField
{
$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 [
'name' => $name,
'type' => $types->string(),

View File

@ -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,
];
}
}

View File

@ -7,11 +7,12 @@ use GraphQL\Examples\Blog\TypeSystem;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\ObjectType;
class ImageType extends BaseType
class ImageType extends ObjectType
{
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',
'fields' => [
'id' => $types->id(),
@ -43,7 +44,9 @@ class ImageType extends BaseType
}
]
]
]);
];
parent::__construct($config);
}
public function resolveUrl(Image $value, $args, AppContext $context)

View File

@ -11,6 +11,7 @@ class MentionType extends BaseType
{
public function __construct(TypeSystem $types)
{
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
$this->definition = new UnionType([
'name' => 'Mention',
'types' => function() use ($types) {

View File

@ -9,12 +9,9 @@ use GraphQL\Type\Definition\InterfaceType;
class NodeType extends BaseType
{
/**
* NodeType constructor.
* @param 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([
'name' => 'Node',
'fields' => [

View File

@ -11,6 +11,7 @@ class QueryType extends BaseType
{
public function __construct(TypeSystem $types)
{
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
$this->definition = new ObjectType([
'name' => 'Query',
'fields' => [

View File

@ -10,6 +10,7 @@ class EmailType extends BaseType
{
public function __construct()
{
// Option #1: define scalar types using composition (see UrlType fo option #2 using inheritance)
$this->definition = new CustomScalarType([
'name' => 'Email',
'serialize' => [$this, 'serialize'],

View File

@ -5,14 +5,9 @@ use GraphQL\Language\AST\StringValue;
use GraphQL\Type\Definition\ScalarType;
use GraphQL\Utils;
/**
* Class UrlTypeDefinition
*
* @package GraphQL\Examples\Blog\Type\Scalar
*/
class UrlTypeDefinition extends ScalarType
class UrlType 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.

View File

@ -23,6 +23,7 @@ class StoryType extends BaseType
public function __construct(TypeSystem $types)
{
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
$this->definition = new ObjectType([
'name' => 'Story',
'fields' => function() use ($types) {

View File

@ -11,6 +11,7 @@ class UserType extends BaseType
{
public function __construct(TypeSystem $types)
{
// Option #1: using composition over inheritance to define type, see ImageType for inheritance example
$this->definition = new ObjectType([
'name' => 'User',
'fields' => function() use ($types) {

View File

@ -5,13 +5,12 @@ use GraphQL\Examples\Blog\Type\CommentType;
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
use GraphQL\Examples\Blog\Type\Enum\ImageSizeEnumType;
use GraphQL\Examples\Blog\Type\Field\HtmlField;
use GraphQL\Examples\Blog\Type\FieldDefinitions;
use GraphQL\Examples\Blog\Type\MentionType;
use GraphQL\Examples\Blog\Type\NodeType;
use GraphQL\Examples\Blog\Type\QueryType;
use GraphQL\Examples\Blog\Type\Scalar\EmailType;
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\ImageType;
use GraphQL\Type\Definition\ListOfType;
@ -129,15 +128,15 @@ class TypeSystem
public function email()
{
return $this->emailType ?: ($this->emailType = new EmailType);
return $this->emailType ?: ($this->emailType = new EmailType());
}
/**
* @return UrlTypeDefinition
* @return UrlType
*/
public function url()
{
return $this->urlType ?: ($this->urlType = new UrlTypeDefinition);
return $this->urlType ?: ($this->urlType = new UrlType());
}
/**