[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()
]
]);
}
}
~~~