[TOC]
#### 定义
枚举类型是一种特殊的标量,限于特定的允许值集合。
枚举类型是 GraphQL\Type\Definition\EnumType (或它的子类) 的实例,它的构造函数接收数组配制参数:
~~~
$episodeEnum = new EnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => [
'NEWHOPE' => [
'value' => 4,
'description' => 'Released in 1977.'
],
'EMPIRE' => [
'value' => 5,
'description' => 'Released in 1980.'
],
'JEDI' => [
'value' => 6,
'description' => 'Released in 1983.'
],
]
]);
~~~
上面的例子用的是内联样式定义 EnumType,同样你也可以使用继承的方式定义。
#### 配制项
|名称 |类型 |描述 |
| --- | --- | --- |
| name | `string` | `必填` 类型名字 |
| description | `string` | 类型的纯文本描述(例如通过GraphQL自动生成文档) |
| values | `array` | 枚举项列表,请参阅下面每个条目的预期结构 |
#### 值配制
values数组的每个条目依次接受以下选项:
| 名称 | 类型 | 描述 |
| --- | --- | --- |
| name | `string` | `必填` 枚举项的名字,当没有指明时,则取数组key值 |
| value | `mixed` | 你应用中 枚举项的内部表示,可以是任意值(包括 复杂对象 及 callbacks) |
| description | `string` | 类型的纯文本描述(例如通过GraphQL自动生成文档) |
| deprecationReason | `string` | 该枚举值弃用原因的描述信息,当不为空时,内省查询 将不返回该字段 (除非includeDeprecated: true,详情请看 内省机制) |
当枚举项的内部表示(即枚举项对应的value值)与该名称相同时,可以使用如下
~~~
$episodeEnum = new EnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => ['NEWHOPE', 'EMPIRE', 'JEDI']
]);
~~~
等同于:
~~~
$episodeEnum = new EnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => [
'NEWHOPE' => 'NEWHOPE',
'EMPIRE' => 'EMPIRE',
'JEDI' => 'JEDI'
]
]);
~~~
等同于
~~~
$episodeEnum = new EnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => [
'NEWHOPE' => ['value' => 'NEWHOPE'],
'EMPIRE' => ['value' => 'EMPIRE'],
'JEDI' => ['value' => 'JEDI']
]
]);
~~~
等同于完整形式
~~~
$episodeEnum = new EnumType([
'name' => 'Episode',
'description' => 'One of the films in the Star Wars Trilogy',
'values' => [
['name' => 'NEWHOPE', 'value' => 'NEWHOPE'],
['name' => 'EMPIRE', 'value' => 'EMPIRE'],
['name' => 'JEDI', 'value' => 'JEDI']
]
]);
~~~
#### 字段解析
**对象字段类型是枚举类型**
当对象字段的类型是枚举类型时,字段解析器(resolve)期望返回相应的枚举项的内部表示(即枚举项的value值),graphql-php然后将该值序列化为名称以包含在响应中。即最后返给客户端的字段值是枚举项名称(如上面的 NEWHOPE 字符串而非真实值 4)。
**当枚举被使用作为输入类型**
当枚举类型作为输入类型使用时(如字段参数 field argument),GraphQL会将枚举输入视为名称,并将其转成对应的值 ( value ) ,然后传递给相应的处理程序。这里说明在client查询体中,传递的字段参数是名称而非对应的值,且不能加引号,如:
~~~
$heroType = new ObjectType([
'name' => 'Hero',
'fields' => [
'appearsIn' => [
'type' => Type::boolean(),
'args' => [
'episode' => Type::nonNull($enumType)
]
'resolve' => function($_value, $args) {
return $args['episode'] === 5 ? true : false;
}
]
]
])
~~~
客户端查询语句
~~~
fragment on Hero {
appearsInNewHope: appearsIn(episode:NEWHOPE)
}
~~~
**注意**
如果字段类型是枚举类型,且其枚举项对应的值(value)是标量(可以是数组),字段解析器(resolve)的值返回类型不同, 只要最终 == 比较相等,则不会出错;但如果枚举项对应的值是对象类型,则会做 === 比较。比如 枚举项值是 1 而 resolve最终返回字符串 "1",不会出错。而如果字段类型是ObjectArray(等其他对象),则始终出错,除非它们引用同一个对象。