🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[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 回调函数实现(它更优先)。 #### 自定义元数据 尚未用到,大家可以看下原始文档