GraphQL學習——查詢與變更

簡介

  • GraphQL是一個用于API的查詢語言,一個使用基于類型系統來執行查詢的服務端運行時
  • GraphQL未與任何特定數據庫,存儲引擎綁定,而是依靠現有代碼和數據支撐

查詢和變更

字段(Fields)

  • GraphQL關于請求對象上的特定字段
  • 查詢和查詢的結果擁有一致的數據結構(很重要)
    • 客戶端得到想要的數據
    • 服務器準確知道客戶端請求的字段
    • 可以對對象字段進行次級選擇
// 查詢
{
  hero {
    name
    # 可以添加備注
    friends {
      name
    }
  }
}

// 結果
{
  "data" : {
    "hero": {
      "name": "wxy",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

參數(Arguments)

  • 每一個字段,嵌套對象都能有自己的一組參數,使得GraphQL可以完美替代多次API獲取請求
  • 可以給標量(scalar)字段傳遞參數,GraphQL自帶一套默認類型,也可以自己定制類型,來序列化輸出格式
    Schema和類型
// 查詢
{
  human(id: "1000") {
    name
    height
  }
}

// 結果
{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 1.72
    }
  }
}

別名(Aliases)

  • 通過別名,查詢相同字段的不同內容
// 查詢不同的hero
{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

// 通過別名,查詢不同的hero
{
  "data": {
    "empireHero": {
      "name": "Luke Skywalker"
    },
    "jediHero": {
      "name": "R2-D2"
    }
  }
}

片段(Fragments)

  • GraphQL可復用單元,好的抽象,可以避免重復代碼
{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

// 結果
{
  "data": {
    "leftComparison": {
      "name": "Luke Skywalker",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "friends": [
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        },
        {
          "name": "C-3PO"
        },
        {
          "name": "R2-D2"
        }
      ]
    },
    "rightComparison": {
      "name": "R2-D2",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }

操作

一個操作query HeroNameAndFriends

  • 操作類型關鍵字——描述打算做什么類型的操作
    • query
    • mutation
    • subscription
  • 操作名稱HeroNameAndFriends
    • 想象成函數名,有利于追蹤和調試

變量(Variables)

  • 查詢參數可能是動態的,GraphQL擁有一級方法將動態值提取到查詢之外,然后作為分離的字典穿進去。這些動態值,就是變量
  • 如何使用變量
    • 使用$variableName替代查詢中的靜態值
    • 聲明$variableName為查詢接收的變量之一
    • variableName: value通過傳輸轉用(通常是JSON)的分離的變量字典中。
  • 用法
// 聲明
query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
// 查詢
{
  "episode": "JEDI"
}
// 結果
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

變量使用注意事項

  • 變量前綴必須為$
  • 聲明變量后跟類型,上例中是Episode
  • 所有聲明的變量都必須是:
    • 標量
    • 枚舉值
    • 輸入對象類型(與服務器有關)
  • 要傳遞一個復雜對象到一個字段上,必須知道服務器上匹配的類型。
  • 變量定義允許:
    • 可選的
    • 必要的,在類型后加!

變量默認值

query HeroNameAndFriends($episode: Episode = "JEDI") {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}

指令(Directives)

  • 指令可以附著在字段或者片段包含的字段上,以服務單期待的方式改變查詢的執行。
  • GraphQL核心規范的兩個指令:
    • @include(if: Boolean)僅在參數為true,包含被指令附著的字段
    • @skip(if: Boolean)如果參數為true,跳過被指令附著的字段

變更(Mutations)

  • 用來變更服務器數據的方法
  • 建議導致寫入的操作都應該顯式的通過變更(mutation)來發送
  • 提價變更同時也可以查詢變更后的對象。
// 聲明變更
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

// 操作
{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}

// 變更后查詢結果
{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

變更中的多個字段

  • 查詢字段,是并行查詢
  • 變更字段,是線性執行,保證了變更不會出現 競爭的情況

內聯片段(Inline Fragments)

  • GraphQL schema 具備自定義接口和聯合類型的能力
  • 若查詢的字段返回的是接口/聯合類型,就需要內聯片段來去處下層具體類型的數據
//聲明
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}
// 操作
{
  "ep": "JEDI"
}
// 結果
{
  "data": {
    "hero": {
      "name": "R2-D2",
      "primaryFunction": "Astromech"
    }
  }
}

元字段(Meta fields)

  • GraphQL允許在查詢的任何位置請求__typename,一個元字段,以獲得那個位置的對象
// 聲明
{
  search(text: "an") {
    __typename
    ... on Human {
      name
    }
    ... on Droid {
      name
    }
    ... on Starship {
      name
    }
  }
}

// 查詢結果
{
  "data": {
    "search": [
      {
        "__typename": "Human",
        "name": "Han Solo"
      },
      {
        "__typename": "Human",
        "name": "Leia Organa"
      },
      {
        "__typename": "Starship",
        "name": "TIE Advanced x1"
      }
    ]
  }
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容

  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,043評論 6 13
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,776評論 18 139
  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優秀的...
    笨鳥慢飛閱讀 5,549評論 0 4
  • 五、Java 虛擬機 一、什么是Java虛擬機Java虛擬機是一個想象中的機器,在實際的計算機上通過軟件模擬來實現...
    壹點零閱讀 747評論 0 0
  • 如果生命是一條河 波濤和麟紋只是調劑 而沉于河底的淤泥才是本質 那么你還會選擇做一條無奈的魚嗎 如果生活是一首歌 ...
    沙清閱讀 364評論 5 1