了解 GraphQL 类型系统

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

GraphQL是一个现代化的解决方案,用于促进前端和数据源之间的通信。 GraphQL 实现的所有细节和功能都包含在 GraphQL Schema中。 为了写出一个运作的 GraphQL 方案,您必须了解 GraphQL 类型系统

在本文中,您将了解 GraphQL 类型:五种内置的 scalar类型, Enums, List 和非 Null包装类型, Object 类型,以及抽象的 InterfaceUnion类型,这些类型与它们一起工作。

前提条件

为了充分利用本教程,你应该:

阶梯类型

所有 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 主题,您可以为游戏字符JobSpecies创建一个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}

这样,可以保证一个字符的JobFIGHTERWIZARD,并且永远不会偶然成为紫色或任何其他随机字符串,如果您使用一个 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 已被声明为 作为值,而武器 字段的参数具有默认值为 ,这意味着如果没有通过,则将返回为

非零类型

您可能会注意到nullundefined,这是许多语言认为原始的常见类型,在嵌入式尺度列表中缺少。

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 生成非 Null ID 类型.
  • name 生成非 Null String 类型.
  • level 生成 Int` 类型
  • active 生成非 Null Boolean 类型

在声明之上,您还可以使用双引文添加评论,如本示例中所示:具有直接战斗能力和力量的英雄

在本示例中,每个字段将分解为一个扩展类型,但对象字段也可以分解为其他对象类型,例如,您可以创建一个武器类型,并且可以设置 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,PUTDELETE类似。

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}

FighterWizard都是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 服务器环境。

Published At
Categories with 技术
comments powered by Disqus