ホームページ  >  記事  >  バックエンド開発  >  GraphQL 型システムの詳細な分析

GraphQL 型システムの詳細な分析

青灯夜游
青灯夜游転載
2023-02-09 20:21:043713ブラウズ

GraphQL 型システムの詳細な分析

GraphQL は、もともと 2012 年に Facebook で非力なモバイル デバイス向けのより優れたデータ取り込みソリューションとして開発されましたが、2015 年にオープンソース化されました。柔軟性を考慮して設計された API テクノロジーである GraphQL は、API の開発者と利用者、さらにはそれらを支える組織にとって強力なイネーブラーです。 GraphQL 実装の詳細と機能はすべて、GraphQL スキーマ にリストされています。有効な GraphQL スキーマ を作成するには、GraphQL 型システム を理解する必要があります。

この記事では、GraphQL の型について学びます: 5 つの組み込みスカラー (scalar) 型、列挙型 (enums)、リスト (list) ) および非 null ラッパー (non-null) 型、オブジェクト (object) 型、および抽象インターフェイスと共用体型 (union)彼らと協力してください。

スカラー型

GraphQL スキーマ内のすべてのデータは、最終的にプリミティブ値を表すさまざまなスカラー型に解析されます。 GraphQL 応答はツリーとして考えることができ、スカラー型はツリーの最後にある葉になります。ネストされた応答には複数のレベルが存在できますが、最後のレベルは常にスカラー (または列挙) 型に解決されます。 GraphQL には、IntFloatStringBooleanID という 5 つの組み込みスカラー型が付属しています。 。

#Int

Int は、符号付き 32 非 10 進値です。小数 (正または負) の整数が含まれます。符号付き 32 桁の整数の最大値は 2,147,483,647 です。これは、数値データ用の 2 つの組み込みスカラーのうちの 1 つです。

Float

Float は、符号付き倍精度 10 進数値です。これは、1.2 など、小数点を含む符号付き (正または負) の数値であり、数値データに使用されるもう 1 つの組み込みスカラーです。

String

String は、UTF-8 文字のシーケンスです。 String タイプはあらゆるテキスト データに使用されます。これには、非常に大きな数値などのデータも含まれる場合があります。ほとんどのカスタム スカラーは文字列データ型です。

ブール値

ブール値には、truefalseが含まれます。

ID

ID は一意の識別子であり、ID が数値であっても常に文字列としてシリアル化されます。 ID 型は、多くの場合、汎用一意識別子 (UUID) で表すことができます。

カスタム スカラー

上記の組み込みスカラーに加えて、scalar キーワードを使用してカスタム スカラーを定義することもできます。カスタム スカラーを使用して、DateTimeUrl などのサーバー レベルの検証を追加した型を作成できます。新しい Date 型を定義する例を次に示します。

scalar Date

サーバーは、GraphQLScalarType を使用して、この新しい型との対話を処理する方法を認識します。

Enumeration (Enum) 型

Enum 型は、Enumerator 型とも呼ばれ、セットを記述するために使用されます。可能な値。

たとえば、システムが受け入れるすべての値を含む、ゲーム キャラクターの Job および Species の列挙を作成できます。

"角色的工作等级"
enum Job {
  FIGHTER
  WIZARD
}

"性格的种类或血统"
enum Species {
  HUMAN
  ELF
  DWARF
}

列挙型を定義すると、ロールの JobFIGHTER または WIZARD のみになり、誤って何かになることがないようにできます。 else Enum の代わりに String 型を使用する場合、一部のランダム文字列は他のランダム文字列になる可能性があります。

列挙型はパラメータの許容値として使用することもできます。たとえば、武器が片手 (短刀など) であるか両手 (重斧など) であるかを表す Hand 列挙を作成し、それを使用して片方か両方かを判断できます。装備可能:

enum Hand {  SINGLE
  DOUBLE}"战士使用的一种武器"type Weapon {
  name: String!
  attack: Int
  range: Int
  hand: Hand
}

type Query {
  weapons(hand: Hand = SINGLE): [Weapon]
}

Hand 列挙型は値として SINGLEDOUBLE を使用して宣言されており、 のパラメータはWeapon フィールドにはデフォルト値 SINGLE があります。つまり、パラメータが渡されない場合、デフォルト値は SINGLE に戻ります。

非空类型

可能会注意到内置标量列表中缺少 nullundefined(一种被许多语言视为原始类型的常见类型)。 Null 在 GraphQL 中确实存在,表示缺少一个值。默认情况下,GraphQL 中的所有类型都可以为 null,因此 null 是对任何类型的有效响应。为了使值成为必需值,必须将其转换为带有尾随感叹号的 GraphQL 非空类型。 Non-Null 被定义为类型修饰符,这些类型用于修饰它所引用的类型。例如,String 是一个可选的(或可为空的)字符串,而 String! 是必需的(或非空的)字符串。

列表类型

GraphQL 中的 List 类型是另一种类型修饰符。任何用方括号 ([]) 括起来的类型都会成为 List 类型,这是一个定义列表中每个项目类型的集合,像 JavaScript 中的数组。

例如,定义为 [Int] 的类型意味着这个集合所有元素的类型为 Int 类型,[String] 将是 String 类型的集合。 Non-NullList 可以一起使用,使一个类型既需要又定义为 List,例如 [String]!

对象类型

如果 GraphQL 标量类型描述分层 GraphQL 响应末尾的“叶子”,那么对象类型描述中间的 分支,并且 GraphQL 模式中的几乎所有内容都是一种对象类型。

对象由命名字段(键)列表和每个字段将解析为的值类型组成。对象是用 type 关键字定义的。至少要定义一个或多个字段,字段不能以两个下划线(__)开头,以免与GraphQL自省系统冲突。

例如创建一个 Fighter 对象来表示游戏中的一种角色:

"具有直接战斗能力和力量的英雄"
type Fighter {
  id: ID!
  name: String!
  level: Int
  active: Boolean!
}

在此示例中,声明了 Fighter 对象类型,定义了 4 个字段:

  • id:非空 ID 类型。
  • name:非空字符串类型。
  • levelInt 类型。
  • active:非空布尔类型。

在声明上方,可以使用双引号添加注释,如本例:具有直接战斗能力和力量的英雄,这将显示为类型的描述。

在此示例中,每个字段都解析为标量类型,但对象字段也可以解析为其他对象类型。例如,可以创建一个 Weapon 类型,并且可以设置 GraphQL 模式,其中 Fighter 上的 weapon 字段将解析为一个 Weapon 对象:

"战士使用的一种武器"
type Weapon {
  name: String!
  attack: Int
  range: Int
}

"具有直接战斗能力和力量的英雄"
type Fighter {
  id: ID!
  name: String!
  level: Int
  active: Boolean!
  weapon: Weapon
}

对象也可以嵌套到其他对象的字段中。

根操作类型

有三种特殊对象作为 GraphQL schema 的入口点:QueryMutationSubcription。这些被称为根操作类型,并遵循与任何其他对象类型相同的规则。

schema 关键字表示 GraphQL 模式的入口点。根 QueryMutationSubcription 类型将位于根模式对象上:

schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}

Query 类型在任何 GraphQL 模式上都是必需的,代表一个读取请求,类似于 REST API GET。以下是返回 Fighter 类型列表的根查询对象的示例:

type Query {
  fighters: [Fighter]
}

Mutations 代表写入请求,类似于 REST API 中的 POSTPUTDELETE。在以下示例中,Mutation 有一个带有命名参数(输入)的 addFighter 字段:

type Mutation {
  addFighter(input: FighterInput): Fighter
}

最后,一个 Subscription 对应于一个事件流,它将与 Web 应用程序中的 Websocket 结合使用。如下所示:

type Subscription {
  randomBattle(enemy: Enemy): BattleResult
}

请注意,schema 入口点通常在某些 GraphQL 实现中被抽象掉。

字段参数

GraphQL 对象的字段本质上是返回值的函数,并且它们可以像任何函数一样接受参数。字段参数由参数名称后跟类型定义,参数可以是任何非对象类型。在此示例中,可以通过 id 字段(解析为非空 ID 类型)过滤 Fighter 对象:

type Query {
  fighter(id: ID!): Fighter
}

这个特定示例对于从数据存储中获取单个项目很有用,但参数也可用于过滤、分页和其他更具体的查询。

接口类型

Object 类型一样,抽象接口类型由一系列命名字段及其关联的值类型组成。接口看起来像并遵循与对象相同的所有规则,但用于定义对象实现的子集。

到目前为止,在 schema 中有一个 Fighter 对象,但可能还想创建一个Wizard、一个 Healer 和其他对象,它们将共享大部分相同的字段但还是存在一些差异。在这种情况下,可以使用接口来定义它们共有的字段,并创建作为接口实现的对象。

在下面的示例中,使用 interface 关键字创建 BaseCharacter 接口,其中包含每种类型的字符将拥有的所有字段:

"A hero on a quest."interface BaseCharacter {
  id: ID!
  name: String!
  level: Int!
  species: Species
  job: Job
}

每个角色类型都有字段 idnamelevelspeciesjob

现在,假设有一个具有这些共享字段的 Fighter 类型和一个 Wizard 类型,但是 Fighters 使用 WeaponWizards 使用 Spells。可以使用 implements 关键字将每个描述为 BaseCharacter 实现,这意味着它们必须具有创建的接口中的所有字段:

type Fighter implements BaseCharacter {
  id: ID!
  name: String!
  level: Int!
  species: Species
  job: Job!
  weapon: Weapon
}
type Wizard implements BaseCharacter {
  id: ID!
  name: String!
  level: Int!
  species: Species
  job: Job!
  spells: [Spell]
}

FighterWizard 都是 BaseCharacter 接口的有效实现,因为它们具有所需的字段子集。

Union 类型

可以与对象一起使用的另一种抽象类型是 union 类型。使用 union 关键字,可以定义一个类型,其中包含所有有效响应的对象列表。

使用上面创建的接口,可以创建一个 Character union,将 character 定义为 WizardFighter

union Character = Wizard | Fighter

等号 = 设置定义,管道符 | 用作 OR 语句。请注意,union 必须由对象或接口组成,标量类型在 union 上无效。

现在,如果查询 characters 列表,它可以使用 Character union 并返回所有 WizardFighter 类型。

总结

上面学习了定义 GraphQL 类型系统的类型,包括最基本的类型是标量类型由 IntFloatStringBooleanID和 GraphQL 实现创建的任何自定义标量类型组成。枚举是有效常量值的列表,当需要对查询响应进行更多控制时,可以使用枚举,而不是简单地将其声明为字符串。列表类型和非空类型被称为类型修饰符 type modifier 或包装类型 wrapping type,它们分别可以将其他类型定义为集合类型或必需类型。GraphQL schema 中的几乎所有内容都是对象类型,包括 querymutationsubscription 入口点。接口和联合类型是抽象类型,在定义对象时很有用。

【相关推荐:Go视频教程编程教学

以上がGraphQL 型システムの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。