# GraphQL 漸進(jìn)學(xué)習(xí) 02-GraphQL-組件構(gòu)成知識(shí)整理

GraphQL 漸進(jìn)學(xué)習(xí) 02-GraphQL-組件構(gòu)成知識(shí)整理

目標(biāo)

  • 對(duì) GraphQL 構(gòu)成的組件進(jìn)行知識(shí)精要整理
  • 組件構(gòu)成有 5 個(gè)方面
    • 查詢變更 queries
    • Schema 和類型 schema
    • 驗(yàn)證 validation
    • 執(zhí)行 execution
    • 內(nèi)省 introspection

方便日后當(dāng)手冊(cè)查閱

代碼

融合上述特性寫(xiě)了個(gè)代碼,方便記憶

查詢變更 queries

查詢變更都是客戶端代碼

字段(Fields)

{
  authors {
    id
    firstName
    lastName
  }
}

參數(shù)(Arguments)

{
  author(id: 1) {
    id
    firstName
    lastName
  }
}

別名(Aliases)

{
  author(id: 1) {
    id
    name: firstName
    lastName
  }
}

片段(Fragments)

{
  author(id: 1) {
    ...authorFields
  }
}

fragment authorFields on Author {
  id
  firstName
  lastName
  posts {
    title
  }
}

操作名稱(Operation name)

query findAuthors {
  authors {
    id
    firstName
    lastName
    posts {
      title
    }
  }
}

變量(Variables)

輸入

# query
query findAuthor($id: Int!) {
  author(id: $id) {
    id
    firstName
    lastName
    posts {
      title
    }
  }
}

# variables
{
  "id": 1
}

輸出

Operation name

默認(rèn)變量(Default variables)

query findAuthor($id: Int = 2) {
  author(id: $id) {
    id
    firstName
    lastName
    posts {
      title
    }
  }
}

指令(Directives)

# query
query findAuthor($id: Int = 1, $withPosts: Boolean!) {
  author(id: $id) {
    id
    firstName
    lastName
    posts @include(if: $withPosts) {
      title
    }
  }
}

# variables
{
  "withPosts": false
}
  • @include(if: Boolean) 僅在參數(shù)為 true 時(shí),包含此字段夭谤。

  • @skip(if: Boolean) 如果參數(shù)為 true 時(shí),跳過(guò)此字段逾柿。

變更(Mutations)

# query
mutation upPost($id: Int!) {
  upvotePost(postId: $id) {
    id
    title
    votes
  }
}

# variables
{
  "id": 1
}

變更中的多個(gè)字段(Multiple fields in mutations)

# query
mutation upPost($id: Int!) {
  upVotePost(postId: $id) {
    id
    title
    votes
  }
  clearVotePost(postId: $id) {
    id
    title
    votes
  }
}

# variables
{
  "id": 1
}

# output
{
  "data": {
    "upVotePost": {
      "id": 1,
      "title": "Introduction to GraphQL",
      "votes": 1
    },
    "clearVotePost": {
      "id": 1,
      "title": "Introduction to GraphQL",
      "votes": 0
    }
  }
}
  • 多個(gè)變更氛什,按順序先后執(zhí)行七芭,但是查詢是并行的

內(nèi)聯(lián)片段(Inline Fragments)

query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}

元字段(Meta fields)

{
  authors {
    __typename
    id
    firstName
    lastName
  }
}
  • __typename 顯示類型名稱

  • 其它元字段秘症,用于描述 內(nèi)省 系統(tǒng)

Schema 和類型 schema

schema 定義是服務(wù)端代碼

對(duì)象類型和字段(Object Types and Fields)

  type Author {
    """
    流水編號(hào)
    """
    id: Int!
    firstName: String
    lastName: String
    """
    用戶發(fā)布的文章
    """
    posts: [Post]
  }
  • type 定義對(duì)象

  • """ 標(biāo)記注釋

  • Int String 系統(tǒng)對(duì)象

  • ! 不能為空

  • [...] 數(shù)組

  • String! 字符串不為空

  • [String]! 數(shù)組不為空

默認(rèn)標(biāo)量類型

  • Int 有符號(hào) 32 位整數(shù)

  • Float 有符號(hào)雙精度浮點(diǎn)值

  • String UTF‐8 字符序列

  • Boolean true 或者 false

  • ID ID 標(biāo)量類型表示一個(gè)唯一標(biāo)識(shí)符照卦,通常用以重新獲取對(duì)象或者作為緩存中的鍵。ID 類型使用和 String 一樣的方式序列化乡摹;然而將其定義為 ID 意味著并不需要可讀型役耕。

自定義類型 scalar

scalar Date

詳細(xì)請(qǐng)移步 03-GraphQL-scalar-自定義類型

枚舉類型(Enumeration Types)

  enum Country {
    CN
    ENG
    JP
    UK
    CA
  }

  type Author {
    """
    流水編號(hào)
    """
    id: Int!
    firstName: String
    lastName: String
    state(state: Country = CN): String
    """
    the list of Posts by this author
    """
    posts: [Post]
  }
  • state 字段指定了枚舉類型,默認(rèn)值 CN

接口(Interfaces)

  interface Message {
    content: String
  }

  type Notice implements Message {
    content: String
    noticeTime: Date
  }

  type Remind implements Message {
    content: String
    endTime: Date
  }

詳細(xì)請(qǐng)移步 04-graphql-resolvers-interfaces-接口的使用

聯(lián)合類型(Union Types)

union MessageResult = Notice | Remind

詳細(xì)請(qǐng)移步 05-graphql-resolvers-union-聯(lián)合的使用

輸入類型(Input Types)

# 定義輸入類型 `AuthorInput`
input AuthorInput {
  firstName: String
  lastName: String
  state: String
}

# 指定變更變量類型
type Mutation {
  addAuthor (
    author: AuthorInput!
  ): Author
}

驗(yàn)證 validation

通過(guò)使用類型系統(tǒng)趟卸,你可以預(yù)判一個(gè)查詢是否有效蹄葱。這讓服務(wù)器和客戶端可以在無(wú)效查詢創(chuàng)建時(shí)就有效地通知開(kāi)發(fā)者氏义,而不用依賴運(yùn)行時(shí)檢查锄列。

執(zhí)行 execution

一個(gè) GraphQL 查詢?cè)诒或?yàn)證后,GraphQL 服務(wù)器會(huì)將之執(zhí)行惯悠,并返回與請(qǐng)求的結(jié)構(gòu)相對(duì)應(yīng)的結(jié)果邻邮,該結(jié)果通常會(huì)是 JSON 的格式。

Query: {
  human(obj, args, context) {
    return context.db.loadHumanByID(args.id).then(
      userData => new Human(userData)
    )
  }
}
  • obj 上一級(jí)對(duì)象克婶,如果字段屬于根節(jié)點(diǎn)查詢類型通常不會(huì)被使用筒严。

  • args 可以提供在 GraphQL 查詢中傳入的參數(shù)。

  • context 會(huì)被提供給所有解析器情萤,并且持有重要的上下文信息比如當(dāng)前登入的用戶或者數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象鸭蛙。

內(nèi)省 introspection

__schema 查詢哪些對(duì)象可用

# 查詢
{
  __schema {
    types {
      name
      kind
    }
  }
}

# 輸出
{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "Query",
          "kind": "OBJECT"
        },
        {
          "name": "Post",
          "kind": "OBJECT"
        },
        {
          "name": "Int",
          "kind": "SCALAR"
        },
        {
          "name": "String",
          "kind": "SCALAR"
        },
        {
          "name": "Author",
          "kind": "OBJECT"
        },
        {
          "name": "Country",
          "kind": "ENUM"
        },
        {
          "name": "Message",
          "kind": "INTERFACE"
        },
        {
          "name": "MessageResult",
          "kind": "UNION"
        },
        {
          "name": "Notice",
          "kind": "OBJECT"
        },
        {
          "name": "Date",
          "kind": "SCALAR"
        },
        {
          "name": "Remind",
          "kind": "OBJECT"
        },
        {
          "name": "Mutation",
          "kind": "OBJECT"
        },
        {
          "name": "AuthorInput",
          "kind": "INPUT_OBJECT"
        },
        {
          "name": "__Schema",
          "kind": "OBJECT"
        },
        {
          "name": "__Type",
          "kind": "OBJECT"
        },
        {
          "name": "__TypeKind",
          "kind": "ENUM"
        },
        {
          "name": "Boolean",
          "kind": "SCALAR"
        },
        {
          "name": "__Field",
          "kind": "OBJECT"
        },
        {
          "name": "__InputValue",
          "kind": "OBJECT"
        },
        {
          "name": "__EnumValue",
          "kind": "OBJECT"
        },
        {
          "name": "__Directive",
          "kind": "OBJECT"
        },
        {
          "name": "__DirectiveLocation",
          "kind": "ENUM"
        }
      ]
    }
  }
}
  • __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - 這些有著兩個(gè)下劃線的類型是內(nèi)省系統(tǒng)的一部分

queryType 查詢對(duì)象名稱

# 查詢
{
  __schema {
    queryType {
      name
    }
  }
}

# 輸出
{
  "data": {
    "__schema": {
      "queryType": {
        "name": "Query"
      }
    }
  }
}

__type 查詢對(duì)象

# 查詢
{
  __type(name: "Notice") {
    name
    kind
    description
    fields {
      name
      type {
        name
      }
      description
    }
    interfaces {
      name
      description
    }
  }
}

# 輸出
{
  "data": {
    "__type": {
      "name": "Notice",
      "kind": "OBJECT",
      "description": "通知對(duì)象",
      "fields": [
        {
          "name": "content",
          "type": {
            "name": "String"
          },
          "description": "通知內(nèi)容"
        },
        {
          "name": "noticeTime",
          "type": {
            "name": "Date"
          },
          "description": "通知時(shí)間"
        }
      ],
      "interfaces": [
        {
          "name": "Message",
          "description": "消息接口"
        }
      ]
    }
  }
}

所有的查詢對(duì)象

# 查詢
{
  __type(name: "Query") {
    name
    kind
    fields {
      name
      description
      args {
        name
        description
        defaultValue
      }
    }
  }
}

# 輸出
{
  "data": {
    "__type": {
      "name": "Query",
      "kind": "OBJECT",
      "fields": [
        {
          "name": "posts",
          "description": "所有文章",
          "args": []
        },
        {
          "name": "authors",
          "description": "所有作者",
          "args": []
        },
        {
          "name": "author",
          "description": "",
          "args": [
            {
              "name": "id",
              "description": "作者ID",
              "defaultValue": null
            }
          ]
        },
        {
          "name": "searchInterface",
          "description": "",
          "args": [
            {
              "name": "text",
              "description": "",
              "defaultValue": null
            }
          ]
        },
        {
          "name": "searchUnion",
          "description": "",
          "args": [
            {
              "name": "text",
              "description": "",
              "defaultValue": null
            }
          ]
        }
      ]
    }
  }
}

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市筋岛,隨后出現(xiàn)的幾起案子娶视,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肪获,死亡現(xiàn)場(chǎng)離奇詭異寝凌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)孝赫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)较木,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人青柄,你說(shuō)我怎么就攤上這事伐债。” “怎么了刹前?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵泳赋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我喇喉,道長(zhǎng),這世上最難降的妖魔是什么拣技? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任千诬,我火速辦了婚禮,結(jié)果婚禮上膏斤,老公的妹妹穿的比我還像新娘徐绑。我一直安慰自己,他們只是感情好莫辨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布傲茄。 她就那樣靜靜地躺著,像睡著了一般沮榜。 火紅的嫁衣襯著肌膚如雪盘榨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天蟆融,我揣著相機(jī)與錄音草巡,去河邊找鬼。 笑死型酥,一個(gè)胖子當(dāng)著我的面吹牛山憨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弥喉,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼郁竟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了由境?” 一聲冷哼從身側(cè)響起棚亩,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蔑舞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拒担,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年攻询,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了从撼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钧栖,死狀恐怖低零,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拯杠,我是刑警寧澤掏婶,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站潭陪,受9級(jí)特大地震影響雄妥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜依溯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一老厌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧黎炉,春花似錦枝秤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至庆械,卻和暖如春薇溃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背干奢。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工痊焊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盏袄,地道東北人忿峻。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辕羽,于是被迫代替她去往敵國(guó)和親逛尚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容