目錄
GraphQL是甚麼
GraphQL是種資料庫查詢語言
其架構是由一個一個的type組成,type內定義了欄位
// type是型別宣告的關鍵字,Capsule則是型別名
type Capsule {
  // 內部是欄位、欄位的型別
  id: ID
  landings: Int
  missions: [CapsuleMission]
  original_launch: Date
  reuse_count: Int
  status: String
  type: String
  dragon: Dragon
}
優點
- 只拿需要的資料
- 極具彈性,資料間可以連來連去,且不像SQL的Join複雜
- 支援型別定義、偵錯,目前有5種預設型別,Int、Float、String、Boolean、ID(String | Int)
缺點
- 無論query是否成功都會得到HTTP code 200,使得難以處理error的情況
- 快取有困難
 官方提到可以用2種方法發request給GraphQL,GET與POST- GET因為網址會帶query string,所以可快取- 只是網址可能會長成這樣,而且 - 帶有變數的request並- 無法使用此方法- // 一定要留空格,空格代表換行 https://api.spacex.land/graphql/?query={ capsules { id missions { name flight } } }- POST的話因為把query轉為JSON,並帶入body,所以- response並- 不會被cache- async function bar(){ const res = await fetch('https://api.spacex.land/graphql/', { method:'POST', body:JSON.stringify({query:"{\n capsules {\n id\n }\n}\n", variables:null}), headers:{ "Content-Type":"application/json; charset=utf-8" } }) return await res.json(); } const {data} = await bar(); console.log(data);- 關於GET與POST可以回顧這篇 
語法
本文使用中的例子是GraphQL playground - space X來進行操作
它的schema滿完整的,只可惜使用的GraphQL版本低於5,故有些功能不能用
field & argument
field就是欄位,有甚麼欄位可以用Docs看
query是operation type,capsuleData是operation name,只有一組query時可以不寫,多組一定要寫,不然會發生衝突
先來看一下型別
// ()內的是argument,:後是型別
capsules(
    find: CapsulesFind
    limit: Int
    offset: Int
    order: String
    sort: String
): [Capsule]
// Capsule的欄位
id: ID
landings: Int
missions: [CapsuleMission]
original_launch: Date
reuse_count: Int
status: String
type: String
dragon: Dragon
語法
query capsuleData {
  capsules(limit:2) { // limit:2是argument,這代表只抓前2筆資料
    id
    missions {
      flight
      name
    }
  }
}
variable
// $id:ID是variable,ID是型別,!代表必填
query capsuleData($id:ID! = "C102"){ // = "C102"是給變數預設值
  capsule(id:$id){
    id
    missions {
      flight
      name
    }
  }
}
下方的Query Variable區域用JSON格式填寫變數
{
  "id":"C101"
}
aliases
和SQL的別名一樣都是為了避免同樣的field導致衝突
query capsuleData {
  C105Data: capsule(id: "C105") { // C105Data是別名
    id
    missions {
      flight
      name
    }
  }
  C101Data: capsule(id: "C101") {
    id
    missions {
      flight
      name
    }
  }
}
fragment
透過fragment建立field set,這可以用在同樣的欄位重複多次出現時(就像前個例子)
argument用於在一坨同型別的資料中根據條件撈資料
{
  // id: "C105"是argument
  leftComparison: capsule(id: "C105") { 
    ...comparisonFields
  }
  rightComparison: capsule(id: "C101") {
    ...comparisonFields
  }
}
// comparisonFields是fragment的名稱,Capsule是型別名
fragment comparisonFields on Capsule { 
  id
  missions {
    flight
    name
  }
}
指令 include
graphql-tools 5+才能用
query capsuleData($limit:Int, $isFligheShow:Boolean!){
  capsules(limit:$limit){
    id
    missions @include(if: $isFligheShow) {
      flight
      name
    }
  }
}
參考資料
GraphQL - queries
Serving over HTTP
GraphQL 入門:初次實作 Schema 與 Resolver
GraphQL 入門: 簡介 X 範例 X 優缺點
GraphQL 入門: Arguments, Aliases, Fragment 讓 Query 更好用 (進階 Query)
HTTP caching in GraphQL
Making GraphQL Requests using HTTP Methods
playgrounds
GraphQL playground - space X
GraphQL Playground Example
PoP API Demo

![[ 筆記 ] React 03 - Functional Componet & Component 之間的溝通](https://static.coderbridge.com/img/krebikshaw/2e98a5866ded4a259ad50a68d1473469.jpg)
