亚洲日本永久一区二区_国产精品k频道网址导航_首页aⅴ色老汉中文字幕_免费深夜全片观看_9久久9毛片又大又硬又粗_国产精品成亚洲电影_日韩不用播放器的av_欧美特色特黄视频

理解 GraphQL 類型系統

理解 GraphQL 類型系統

GraphQL 最初于 2012 年在 Facebook 開發,作為針對動力不足的移動設備的更好的數據獲取解決方案,GraphQL 于 2015 年開源。作為一種為靈活性而設計的 API 技術,GraphQL 是 API 的開發人員和消費者以及他們背后的組織的強大推動者。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

非空類型

可能會注意到內置標量列表中缺少 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 入口點。接口和聯合類型是抽象類型,在定義對象時很有用。