Maison  >  Article  >  développement back-end  >  Une analyse approfondie du système de type GraphQL

Une analyse approfondie du système de type GraphQL

青灯夜游
青灯夜游avant
2023-02-09 20:21:043712parcourir

Une analyse approfondie du système de type GraphQL

Développé à l'origine par Facebook en 2012 comme meilleure solution d'ingestion de données pour les appareils mobiles sous-alimentés, GraphQL a été open source en 2015. En tant que technologie API conçue pour la flexibilité, GraphQL est un outil puissant pour les développeurs et les consommateurs d'API, ainsi que pour les organisations qui les sous-tendent. Tous les détails et fonctionnalités de l'implémentation de GraphQL sont répertoriés dans Schéma GraphQL. Afin d'écrire un schéma GraphQL valide, vous devez comprendre Système de types GraphQL. GraphQL Schema 中列出。为了编写一个有效的 GraphQL schema,必须理解好 GraphQL 类型系统

在本文中,将学习 GraphQL 类型:五种内置标量(scalar)类型、枚举(enums)、列表(list)和非空包装(non-null)类型、对象(object)类型以及与它们一起工作的抽象接口和联合类型(union)。

标量类型

GraphQL 模式中的所有数据最终都解析为各种标量类型,代表原始值。GraphQL 响应可以看作一棵树,标量类型是树末端的叶子。嵌套响应中可以有多个级别,但最后一个级别将始终解析为标量(或枚举)类型。 GraphQL 带有五种内置标量类型:IntFloatStringBooleanID

Int

Int 是带符号的 32 位非小数值,它是不包括小数的带符号(正或负)整数。带符号的 32 位整数的最大值为 2,147,483,647。这是用于数值数据的两个内置标量之一。

Float

Float 是带符号的双精度小数值。它是一个带小数点的有符号(正或负)数,例如 1.2,这是用于数值数据的另一个内置标量。

String

StringUTF-8 字符序列。 String 类型用于任何文本数据,这也可以包括非常大的数字等数据。大多数自定义标量都是字符串数据类型。

Boolean

Boolean 包含 truefalse

ID

ID 是唯一标识符,始终序列化为字符串,即使 ID 是数字也是如此。ID 类型通常可以用通用唯一标识符 (UUID) 表示。

自定义标量

除了上述这些内置标量之外,还可以使用 scalar 关键字来定义自定义标量。可以使用自定义标量来创建具有额外服务器级别验证的类型,例如 DateTimeUrl。下面是一个定义新 Date 类型的示例:

scalar Date

服务器将知道如何使用 GraphQLScalarType 处理与这种新类型的交互。

枚举(Enum)类型

Enum 类型,也称为 Enumerator 类型,用于描述了一组可能的值。

例如可以为游戏角色的 JobSpecies 创建一个枚举,其中包含系统将接受的所有值。

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

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

通过定义枚举类型可以保证角色的 Job 只能是 FIGHTERWIZARD,并且永远不会意外地成为其他一些随机字符串,如果使用 String 类型而不是 Enum,那么就有可能是别的随机字符串。

枚举也可以用作参数中的可接受值。例如,可以制作一个 Hand 枚举来表示武器是单手(如短剑)还是双手(如重斧),并使用它来确定是否可以装备一个或两个:

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

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

Hand 枚举已声明为 SINGLEDOUBLE 作为值,weapons 字段上的参数具有默认值 SINGLE,这意味着如果未传递任何参数,它将回默认为 SINGLE

Dans cet article, vous apprendrez les types GraphQL : cinq types scalaires intégrés (scalar), les énumérations (enums), les listes (list ) et les types wrapper non nuls (non-null), les types d'objets (object), ainsi que les interfaces abstraites et les types d'union (union qui travaillent avec eux >). 🎜

Types scalaires

🎜Toutes les données d'un schéma GraphQL sont finalement analysées en différents types scalaires, représentant des valeurs primitives. Une réponse GraphQL peut être considérée comme un arbre, les types scalaires étant les feuilles à la fin de l'arbre. Il peut y avoir plusieurs niveaux dans une réponse imbriquée, mais le dernier niveau sera toujours résolu en un type scalaire (ou énumération). GraphQL est livré avec cinq types scalaires intégrés : Int, Float, String, Boolean et Identifiant. 🎜<h4 data-id="heading-1"><strong>Int</strong></h4>🎜<code>Int est une valeur non décimale signée 32 chiffres , qui est un entier signé (positif ou négatif) excluant les décimales. La valeur maximale pour un entier signé 32 bits est 2 147 483 647. Il s'agit de l'un des deux scalaires intégrés pour les données numériques. 🎜

Float

🎜Float est une valeur décimale signée à double précision. Il s'agit d'un nombre signé (positif ou négatif) avec un point décimal, tel que 1.2, qui est un autre scalaire intégré utilisé pour les données numériques. 🎜

String

🎜String est une séquence de caractères UTF-8. Le type String est utilisé pour toutes les données texte, qui peuvent également inclure des données telles que de très grands nombres. La plupart des scalaires personnalisés sont des types de données chaîne. 🎜

Booléen

🎜Booléen contient true et false code>. 🎜<h4 data-id="heading-5"><strong>ID</strong></h4>🎜<code>ID est un identifiant unique et est toujours sérialisé sous forme de chaîne, même si Il en va de même pour l'ID étant un numéro. Le type ID peut généralement être représenté par un identifiant universellement unique (UUID). 🎜

Scalaire personnalisé

🎜En plus des scalaires intégrés ci-dessus, vous pouvez également utiliser le scalaire mot-clé pour définir un scalaire personnalisé. Vous pouvez utiliser des scalaires personnalisés pour créer des types avec une validation supplémentaire au niveau du serveur, tels que Date, Time ou Url. Voici un exemple de définition d'un nouveau type Date : 🎜
"具有直接战斗能力和力量的英雄"
type Fighter {
  id: ID!
  name: String!
  level: Int
  active: Boolean!
}
🎜Le serveur saura utiliser GraphQLScalarType gère l'interaction avec ce nouveau type. 🎜

Type Enum

🎜Le type Enum, également appelé type Enumerator, est utilisé pour décrire un ensemble de valeurs possibles. 🎜🎜Par exemple, vous pouvez créer une énumération pour le Job et l'Espèce de votre personnage de jeu qui contient toutes les valeurs que le système acceptera. 🎜
"战士使用的一种武器"
type Weapon {
  name: String!
  attack: Int
  range: Int
}

"具有直接战斗能力和力量的英雄"
type Fighter {
  id: ID!
  name: String!
  level: Int
  active: Boolean!
  weapon: Weapon
}
🎜En définissant un type d'énumération, vous pouvez vous assurer que le Job du rôle ne peut être que FIGHTER ou WIZARD, et ne deviendra jamais accidentellement un autre Chaîne aléatoire, si vous utilisez le type String au lieu de Enum, il peut s'agir d'une autre chaîne aléatoire. 🎜🎜Les énumérations peuvent également être utilisées comme valeurs acceptables dans les paramètres. Par exemple, vous pouvez faire une énumération Main pour représenter si l'arme est à une main (comme une épée courte) ou à deux mains (comme une hache lourde), et l'utiliser pour déterminer si une ou deux mains sont utilisées. les deux peuvent être équipés : 🎜
schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}
🎜 L'énumération Hand a été déclarée avec SINGLE et DOUBLE comme valeurs, et les paramètres sur le Le champ Weapons a des valeurs par défaut SINGLE, ce qui signifie que si aucun paramètre n'est transmis, il sera par défaut 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视频教程编程教学

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer