[TOC]
#### 定義
Object Type
對象類型是典型 GraphQL 應用中使用最頻繁的基本類型。
概念上對象類型是字段的集合,每個字段又有自己的類型,允許構建復雜的層次結構。
示例:
~~~
namespace MyApp;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Examples\Blog\Data\DataSource;
use GraphQL\Examples\Blog\Data\Story;
$userType = new ObjectType([
'name' => 'User',
'description' => 'Our blog visitor',
'fields' => [
'firstName' => [
'type' => Type::string(),
'description' => 'User first name'
],
'email' => Type::string()
]
]);
$blogStory = new ObjectType([
'name' => 'Story',
'fields' => [
'body' => Type::string(),
'author' => [
'type' => $userType,
'description' => 'Story author',
'resolve' => function(Story $blogStory) {
return DataSource::findUser($blogStory->authorId);
}
],
'likes' => [
'type' => Type::listOf($userType),
'description' => 'List of users who liked the story',
'args' => [
'limit' => [
'type' => Type::int(),
'description' => 'Limit the number of recent likes returned',
'defaultValue' => 10
]
],
'resolve' => function(Story $blogStory, $args) {
return DataSource::findLikes($blogStory->id, $args['limit']);
}
]
]
]);
~~~
上面的例子使用的是內聯樣式定義類型,你同樣可以使用繼承方式定義。
#### 配制
對象類型 構造函數 接收一個數組配制項,下面是可用配制參數的列表。
| 名稱 | 類型 | 描述 |
| --- | --- | --- |
| name | `string` | `必填` 對象類型在Schema內的唯一名字 |
| fields | `array` 或 `callback` (返回 `array`) | `必填` 這個對象類型所有字段,參照下面的字段配制 |
| description | `string` | 類型的純文本描述(例如通過GraphQL自動生成文檔) |
| interfaces | `array` 或 `callback` (返回 `array`) | 類型實現的接口列表 |
| isTypeOf | `callback` return `boolean` | 父類型(或rootValue)傳遞給此類型的值,如果該值適合此類型,應該返回true,否則返回false拋出錯誤 |
| resolveField | `callback` returning `mixed` | **function($value, $args, $context, GraphQL\Type\Definition\ResolveInfo $info)** 傳給這個類型的值,它期望返回當前解析字段($info-> fieldName)值。 為字段解析定義特殊類型策略的好地方 |
#### 字段配制
|名稱 | 類型 | 描述 |
| --- | --- | --- |
| name | `string` | `必填` 字段名字,當沒有指明時,則取數組key值 |
| type | `type` | `必填` 內置或自定義的類型的實例, 注意:類型必須由schema內的單個實例表示。(可以查看 [Type Registry](#type_registry)) |
| args | `array` | 字段參數數組 每個條目期望一個由以下key值組成的數組:name、type、description,defaultValue 。(查看下面的 [字段參數](#field_arguments) ) |
| resolve | `callback` | **function($value, $args, $context, GraphQL\Type\Definition\ResolveInfo $info)** 字段解析器,將 $value 傳給回調函數,期望返回當前字段的值。記住,它的優先級高于resolveField |
| description | `string` | 字段的純文本描述 (例如可以用來自動生成文檔) |
| deprecationReason | `string` | 棄用原因的描述信息,當不為空時,內省查詢 將不返回該字段 (除非includeDeprecated: true,詳情請看 內省機制) |
#### 字段參數配制
Graphql 的對象類型的每個字段能夠有0個或多個參數。
| 名稱 | 類型 | 描述 |
| --- | --- | --- |
| name | `string` | `必填` 參數名字,當沒有指明時,則取數組key值 |
| type | `type` | InputType 其中一個的實例(scalar,enum,InputObjectType + 或是那些和nonNull 或 listOf 修飾符的組合) |
| description | `string` | 字段的純文本描述 (例如可以用來自動生成文檔) |
| defaultValue | `scalar` | 這個字段參數的默認值 |
#### 字段定義簡寫
字段定義可以使用簡寫表示法(當只有名字 和類型 參數時)
~~~
'fields' => [
'id' => Type::id(),
'fieldName' => $fieldType
]
~~~
等同于
~~~
'fields' => [
'id' => ['type' => Type::id()],
'fieldName' => ['type' => $fieldName]
]
~~~
等同于完整形式
~~~
'fields' => [
['name' => 'id', 'type' => Type::id()],
['name' => 'fieldName', 'type' => $fieldName]
]
~~~
相同的簡寫表示同樣適用字段參數
#### 循環類型
現實生活中的應用幾乎都包含循環或循環類型,想想用戶朋友或嵌套評論。
graphql允許這樣的類型, 但是配制參數 fields(或interfaces)你必須使用 callback
~~~
$userType = new ObjectType([
'name' => 'User',
'fields' => function() use (&$userType) {
return [
'email' => [
'type' => Type::string()
],
'friends' => [
'type' => Type::listOf($userType)
]
];
}
]);
~~~
通過 Type Registry 讓繼承方式類型定義 實現 同樣的例子
~~~
namespace MyApp;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ObjectType;
class UserType extends ObjectType
{
public function __construct()
{
$config = [
'fields' => function() {
return [
'email' => MyTypes::string(),
'friends' => MyTypes::listOf(MyTypes::user())
];
}
];
parent::__construct($config);
}
}
class MyTypes
{
private static $user;
public static function user()
{
return self::$user ?: (self::$user = new UserType());
}
public static function string()
{
return Type::string();
}
public static function listOf($type)
{
return Type::listOf($type);
}
}
~~~
#### 字段解析器
Field Resolution
字段解析器是GraphQL用于返回字段實際數據的主要機制。它在類型定義使用 resolveField 回調函數實現 ,或在字段定義中通過 resolve 回調函數實現(它更優先)。
#### 自定義元數據
尚未用到,大家可以看下原始文檔