[toc]
#### 类型系统
要开始使用`GraphQL`,你需要实现一个`type`层次结构并将之公开为`Schema`。
在`graphql-php`中`type`是来自`GraphQL\Type\Definition`命名空间(`ScalarType`,`ObjectType`,`InterfaceType`,`UnionType`,`InputObjectType`)的内部类(或其子类)的实例。
你的`schema`中的大部分类型都是`object types`。
#### 类型定义风格
根据你的喜好,支持几种风格的定义类型。
##### 内联定义
~~~
namespace MyApp;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
$myType = new ObjectType([
'name' => 'MyType',
'fields' => [
'id' => Type::id()
]
]);
~~~
##### 每个类型定义一个类
~~~
namespace MyApp;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
class MyType extends ObjectType
{
public function __construct()
{
$config = [
// Note: 'name' is not needed in this form:
// it will be inferred from class name by omitting namespace and dropping "Type" suffix
'fields' => [
'id' => Type::id()
]
];
parent::__construct($config);
}
}
~~~
#### 类型注册
每个类型在`Schema`中必须通过单个实例(当graphql-php在`schema`中发现具有相同名字的多个实例会抛出异常)表示。
因此,如果你通过单独的`class` 定义`type`,你必须确保只有该类的唯一一个实例添加到`schema`中。
做到上面这些典型的方法是创建你的类型注册表。
~~~
namespace MyApp;
class TypeRegistry
{
private $myAType;
private $myBType;
public function myAType()
{
return $this->myAType ?: ($this->myAType = new MyAType($this));
}
public function myBType()
{
return $this->myBType ?: ($this->myBType = new MyBType($this));
}
}
~~~
在你的类型定义中使用这个注册表。
~~~
namespace MyApp;
use GraphQL\Type\Definition\ObjectType;
class MyAType extends ObjectType
{
public function __construct(TypeRegistry $types)
{
parent::__construct([
'fields' => [
'b' => $types->myBType()
]
]);
}
}
~~~
很显然,因为你期望减少冗余,你可以自动化这个注册表,甚至引用依赖注入窗口如果你的类型有其它依赖的话。
或者,如果你愿意的话,注册表中的所有方法都可以是静态的,然后你不再需要将实例化的TypeRegistry传入类型定义的构造函数,而只需要在类型定义中使用`TypeRegistry::MyAType()`。
使用静态方法重新定义注册表类:
~~~
namespace MyApp;
class TypeRegistry
{
private $myAType;
private $myBType;
public static function myAType()
{
return self::$myAType ?: (self::$myAType = new MyAType());
}
public function myBType()
{
return self::$myBType ?: (self::$myBType = new myBType());
}
}
~~~
定义类型
~~~
namespace MyApp;
use GraphQL\Type\Definition\ObjectType;
class MyAType extends ObjectType
{
public function __construct()
{
parent::__construct([
'fields' => [
'b' => $types::myBType()
]
]);
}
}
~~~