學習 GraphQL 筆記(二)Query Schema

上一篇學完了怎麼定義看得到的資料格是,這一篇就要來學習 Front End 要怎麼取得資料。下面是 Query Schema 的格式:

Operation
GraphQL 提供三個 operation type — query、mutation、subscription。operation type 省略不寫的話,預設會使用 query 來處理。如果一次有多個操作的話,則不能省略。但是建議不要省略,這樣在維護上比較易讀。Operation Name 沒有特別意義,只是幫助區分和維護。
// 不能省略
query {
search {
name
}
}
mutation {
create(text: "man") {
text
}
}
Arguments
Schema 也跟 Object Type 一樣可以帶入參數,來搜尋特定的資料。也可以在參數傳入 Scalar,告訴 GraphQL 在回傳給前端時幫沒做型態的轉換。
{
human(id: "1000") {
name
height(unit: FOOT)
}
}
Alias
從上面的 Argument,我們可以搜尋出特定條件下的參數。但是有時候我們需要找尋不只一個特定條件的資料,但是相同的名稱又會造成衝突,這時候就可以使用 Alias 來避免這個問題
{
son: cat(name: "popping") {
name
color
}
daughter: cat(name: "hino") {
name
color
}
}
Fragment
上一篇在 Interface & Union 內有提到的 Inline Fragment 就是屬於這邊的範疇。Fragment 主要是用於當查詢的結構重複的時候,可以避免冗長的方法。不適用於 Input、Scalar 和 Enum。以上面為例:
fragment basic on Cat {
name
color
}
{
son: cat(name: "popping") {
...basic
}
daughter: cat(name: "hino") {
...basic
}
}
另外 Fragment 也是可以嵌 Fragment 的,上面的例子可以再改為下面的範例,輸出都是一樣的:
fragment min on Cat {
color
}
fragment basic on Cat {
name
...min
}
{
son: cat(name: "popping") {
...basic
}
daughter: cat(name: "hino") {
...basic
}
}
Inline Fragment
主要搭配 Interface & Union 來做使用,可以取出特定 Object Type 的資料,當 Type 和 Object Type 有匹配時,才會回傳資料
Variables
上面介紹的 Argument 是屬於靜態的傳入,值是固定的。但是大多數的使用情境還是動態的傳入資料,這時候就需要使用 Variables。變數需要在 Operation Name 先宣告,如果沒有使用的話就需求移除,不然會檢驗不過。
# 變數須以 $ 為前綴,Scalar 後面可設定預設值
query HeroNameAndFriends($episode: Episode = "JEDI") {
# 上方只是定義,這邊才是真的把變數傳入
hero(episode: $episode) {
name
friends {
name
}
}
}
Directives
在有些使用情境下,有時候會依靠變數去改變的不是搜尋特定的資料,而是要去改變查詢資料的結構。GraphQL 就有提供 Directives 來去使用,內建提供 @skip 和 @include 。
@include:當參數為 true 時包含此 Field@skip:當參數為 true 時略過此 Field
# 需要定義使用的地方,且只能使用在定義的地方
# 不確定是否真的需要定義,有試過沒定義也能使用
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
query myQuery($someTest: Boolean) {
experimentalField @skip(if: $someTest)
}
額外資訊
這邊要特別提到,其實 GraphQL 背後還是使用 HTTP 在傳輸請求的,所以 Server 需要可以支援 GET 和 POST。GraphQL 是把參數轉換成 JSON 的格式
{
**"operationName"**:"myQuery",
**"variables"**:{
},
**"query"**:"query myQuery($someTest: Boolean = true) {\n animal {\n name\n weight @skip(if: $someTest)\n height\n }\n}\n"
}
operationName:定義的 operation name
variables:上面介紹的變數,在這邊傳給 Server
query:GraphQL 的操作,用
JSON.stringify來字串化