[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 回调函数实现(它更优先)。
#### 自定义元数据
尚未用到,大家可以看下原始文档