作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
GraphQL是一个现代化的解决方案,用于促进前端和数据源之间的通信。 GraphQL 实现的所有细节和功能都包含在 GraphQL Schema中。 为了写出一个运作的 GraphQL 方案,您必须了解 GraphQL 类型系统。
在本文中,您将了解 GraphQL 类型:五种内置的 scalar类型, Enums, List 和非 Null包装类型, Object 类型,以及抽象的 Interface和 Union类型,这些类型与它们一起工作。
前提条件
为了充分利用本教程,你应该:
- 对 GraphQL 的基本概念的理解,这些概念在 An Introduction to GraphQL中描述。
- 一个 GraphQL 环境,其中一个例子可以在 如何在 Node.js 中设置 GraphQL API 服务器中找到。
阶梯类型
所有 GraphQL 方案中的数据最终会分解为各种 scalar 类型,这些类型代表原始值。 GraphQL 响应可以被表示为树,而 scalar 类型是树的尽头的叶子。
《Int》
Int
是一個簽署的 32 位非分數數值. 它是一個簽署的 (正或陰性)整數,不包括十分數。 簽署的 32 位整數的最大值是 2,147,483,647
。
海军
一个 Float
是一个签署的双精度分数值. 这是一个签署的(正面或负面的)数字,其中包含一个十进制点,例如 1.2
. 这是用于数字数据的其他内置尺度。
《String》
一个 String
是一个 UTF-8 字符序列. 用于任何文本数据的 String
类型. 这也可以包括非常大的数字等数据。
《Boolean》
一个(‘Boolean’)(https://spec.graphql.org/June2018/#sec-Boolean)是真
或假
的值。
《ID》
一个 ID
是一个独特的标识符。这个值总是作为一个字符串进行序列化,即使ID
是数字的。
常规滑板
除了这些内置的尺度,可以使用尺度
关键字来定义自定义尺度,您可以使用自定义尺度创建具有额外服务器级验证的类型,如日期
,时间
或URL
。
1scalar Date
服务器将知道如何使用 GraphQLScalarType
来处理这种新类型的交互。
一种类型
Enum 类型,也称为 Enumerator 类型,描述了一组可能的值。
使用《如何使用 GraphQL 管理数据》(LINK0)系列中的其他教程中的幻想游戏 API 主题,您可以为游戏字符Job
和Species
创建一个enum
,其中包含系统接受的所有值。
1"The job class of the character."
2enum Job {
3 FIGHTER
4 WIZARD
5}
6
7"The species or ancestry of the character."
8enum Species {
9 HUMAN
10 ELF
11 DWARF
12}
这样,可以保证一个字符的Job
是FIGHTER
或WIZARD
,并且永远不会偶然成为紫色
或任何其他随机字符串,如果您使用一个 String
类型而不是创建一个自定义Enum,则可能有可能。
例如,你可以创建一个手``enum
,表示武器是否是单手(如短剑)或双手(如重斧),并使用它来确定是否可以装备一个或两个:
1enum Hand {
2 SINGLE
3 DOUBLE
4}
5
6"A valiant weapon wielded by a fighter."
7type Weapon {
8 name: String!
9 attack: Int
10 range: Int
11 hand: Hand
12}
13
14type Query {
15 weapons(hand: Hand = SINGLE): [Weapon]
16}
手
enum
已被声明为 单
和 双
作为值,而武器
字段的参数具有默认值为 单
,这意味着如果没有通过,则将返回为 单
。
非零类型
您可能会注意到null
或undefined
,这是许多语言认为原始的常见类型,在嵌入式尺度列表中缺少。
GraphQL 中的所有类型都是默认可取消的,因此null
是任何类型的有效答案。为了使需要的值,它必须被转换为 GraphQL Non-Null类型,具有后续的呼叫点。Non-Null
被定义为类型修改器,这些类型用于修改它所指的类型。
列表类型
GraphQL 中的 List 类型是另一个类型更改器. 任何被包装成方块([]
)的类型都会成为一个列表类型,该类型是定义列表中的每个项目类型的集合。
例如,定义为[Int]
的类型将是Int
类型的集合,而[String]
将是String
类型的集合。
对象类型
如果 GraphQL 尺度类型在等级 GraphQL 响应的末尾描述了叶子
,那么 Object类型描述了中间的分支
,并且 GraphQL 方案中的几乎所有东西都是一个 Object 类型。
对象由一个列表的命名字段(键)和每个字段将解决的值类型组成。对象是用类型
的关键字定义的。
在 GraphQL 幻想游戏 API 示例中,您可以创建一个战斗机
对象来代表游戏中的一个字符类型:
1"A hero with direct combat ability and strength."
2type Fighter {
3 id: ID!
4 name: String!
5 level: Int
6 active: Boolean!
7}
在本示例中,已宣布战斗机
对象类型,并且有四个命名字段:
id
生成非 NullID
类型.name
生成非 NullString
类型.level
生成 Int` 类型active
生成非 NullBoolean
类型
在声明之上,您还可以使用双引文添加评论,如本示例中所示:具有直接战斗能力和力量的英雄
。
在本示例中,每个字段将分解为一个扩展类型,但对象字段也可以分解为其他对象类型,例如,您可以创建一个武器
类型,并且可以设置 GraphQL 方案,在战斗机
上的武器
字段将分解为一个武器
对象:
1"A valiant weapon wielded by a fighter."
2type Weapon {
3 name: String!
4 attack: Int
5 range: Int
6}
7
8"A hero with direct combat ability and strength."
9type Fighter {
10 id: ID!
11 name: String!
12 level: Int
13 active: Boolean!
14 weapon: Weapon
15}
对象也可以嵌入到其他对象的域中。
根操作类型
有三个特殊的对象作为 GraphQL 方案的入口点:查询、突变和订阅.这些被称为 根操作类型,并遵循与任何其他对象类型相同的规则。
您的根查询、突变和订阅类型将位于根schema
对象上:
1schema {
2 query: Query
3 mutation: Mutation
4 subscription: Subscription
5}
任何 GraphQL 方案都需要查询类型,并且代表一个读取请求,类似于 REST API GET
。
1type Query {
2 fighters: [Fighter]
3}
突变代表写请求,在 REST API 中与POST
,PUT
或DELETE
类似。
1type Mutation {
2 addFighter(input: FighterInput): Fighter
3}
最后,订阅对应于一个事件流,它将与Websocket(https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)在Web应用程序中使用,在GraphQL Fantasy API中,它可能用于随机战斗,如下:
1type Subscription {
2 randomBattle(enemy: Enemy): BattleResult
3}
请注意,在一些 GraphQL 实现中,方案
入口点通常被抽象化。
领域论点
GraphQL 对象的字段基本上是返回值的函数,它们可以像任何函数一样接受参数。 字段参数由参数的名称,然后是类型定义。
1type Query {
2 fighter(id: ID!): Fighter
3}
此特定示例可用于从数据存储中提取单个项目,但可以使用参数来过滤、页化和其他更具体的查询。
接口类型
与对象类型一样,抽象的 接口类型由命名字段和它们相关的值类型列表组成,接口看起来和遵循与对象相同的规则,但用于定义对象实现的子集。
到目前为止,在你的计划中,你有一个战斗机
对象,但你可能还想创建一个魔法师
,一个治疗师
和其他对象,这些对象将共享许多相同的领域,但有几个差异。
在下面的示例中,您可以使用接口
关键字创建一个BaseCharacter
接口,其中包含每个字符类型的所有字段:
1"A hero on a quest."
2interface BaseCharacter {
3 id: ID!
4 name: String!
5 level: Int!
6 species: Species
7 job: Job
8}
每个字符类型将有id
,名称
,水平
,物种
和工作
字段。
现在,想象一下你有一个具有这些共享字段的战斗机
类型和魔法师
类型,但战斗机
使用武器
和魔法师
使用拼图
。
1"A hero with direct combat ability and strength."
2type Fighter implements BaseCharacter {
3 id: ID!
4 name: String!
5 level: Int!
6 species: Species
7 job: Job!
8 weapon: Weapon
9}
10
11"A hero with a variety of magical powers."
12type Wizard implements BaseCharacter {
13 id: ID!
14 name: String!
15 level: Int!
16 species: Species
17 job: Job!
18 spells: [Spell]
19}
Fighter
和Wizard
都是BaseCharacter
接口的有效实现,因为它们具有所需的字段子集。
联盟类型
另一个可用于 Objects 的抽象类型是 Union 类型。 使用union
关键字,您可以定义一个类型,其中列出了所有作为响应有效的 Objects。
使用在上一节创建的界面,您可以创建一个字符
联盟,将一个字符定义为魔法师
或战士
:
1union Character = Wizard | Fighter
平等字符 (=
) 定义了定义,管道字符 (███
) 作为OR
语句。 请注意,一个联盟必须由对象或接口组成。
现在,如果您查询一个字符列表,它可以使用字符
联盟并返回所有巫师
和战斗员
类型。
结论
在本教程中,您了解了许多定义 GraphQL 类型系统的类型)。最基本的类型是 scalar 类型,这些类型是作为架构树上的叶片起作用的值,包括Int
,Float
,String
,Boolean
,ID
,以及一个 GraphQL 实现决定创建的任何自定义尺度。Enums是有效的恒定值列表,当您需要对响应进行更多的控制时,而不是简单地宣布它为字符串
,并且也是架构树上的叶片。列表和非Null类型被称为类型修改器,包装类型,它们可以定义其他类型作为集合或相应要求。对象是架构树的分支,并且几乎所有在 GraphQL 架构
为了进一步学习,您可以通过阅读 如何在 Node.js 中设置 GraphQL API 服务器教程来练习创建和修改 GraphQL 架构,以便有一个工作 GraphQL 服务器环境。