目錄
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與POSTGET
因為網址會帶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