iT邦幫忙

1

GraphQL介紹-3 Aliases,Fragments,Operation Name

zyx 2023-02-22 18:09:36738 瀏覽
  • 分享至 

  • xImage
  •  

已經會CRUD了,還要學什麼?

再來是介紹一些個人覺得在GraphQL裡比較花俏的操作,雖然說是花俏,但使用的恰當的話同樣可以幫助我們更好的維護程式

不學會怎樣嗎?

其實當初筆者在學習GraphQL時,直接跳過了這一篇和下一篇提到的內容,就開始使用GraphQL建立後端的Server了,也是在一段時間後才回來補這段GraphQL的技術(知識),所以如果讀者非常期待(急著)能看到結果的話,可以直接跳過這一篇和下一篇直接進入實戰環節

Aliases

why use?

還記得前面有提到我們可以把兩個query包在同一個request嗎?但如果今天我要同時查meals裡面的牛肉麵和水餃的資料可以怎麼做?
步驟1.找出全部的meal,所以使用meals進行查詢
https://ithelp.ithome.com.tw/upload/images/20230222/20144476QOT0OXdbSD.png
再來就是問題所在了,如果我想要對水餃和牛肉麵的價格進行編輯,以前端來說,可以在資料列表看到它們兩後"分別"點擊它們對他們進行編輯
https://ithelp.ithome.com.tw/upload/images/20230222/20144476hXOYg4AMaI.png
例如我們邊點擊水餃後大概會看到類似這樣的前端頁面,讓我可以進行編輯
https://ithelp.ithome.com.tw/upload/images/20230222/20144476OH7m04qA4g.png
對於User來說他需要點點水餃編輯完後再點牛肉麵進行編輯,這樣的設計使他不能一次編輯多筆資料,可能會讓他使用起來有些不方便,因此我們可以設計成類似這樣的畫面
https://ithelp.ithome.com.tw/upload/images/20230222/20144476Iq5zrfmjRA.png
理論上我們選完了牛肉麵和水餃,並且知道了他們的id應該就是把兩個meal的完整資料在表單,透過以下語法進行查詢

query{
  meal(id:"58811ae5-1471-4366-844b-2886b3abccf1"){
    id
    itemName
    price
  }
  meal(id:"19506d93-d6dc-486e-8b08-5c6045f8d348"){
    id
    itemName
    price
  }
}

然後就出事情了,語法並不支持我們這樣做
https://ithelp.ithome.com.tw/upload/images/20230222/20144476LrwPrC8cYG.png
因此我們需要使用Aliases來替我們解決問題,使用方法為

# Write your query or mutation here
query{
  meal1: meal(id:"58811ae5-1471-4366-844b-2886b3abccf1"){
    id
    itemName
    price
  }
  meal2: meal(id:"19506d93-d6dc-486e-8b08-5c6045f8d348"){
    id
    itemName
    price
  }
}

https://ithelp.ithome.com.tw/upload/images/20230222/20144476bm05DmjqK6.png
因此我們大概會在前端看到這樣的畫面
https://ithelp.ithome.com.tw/upload/images/20230222/20144476cHSTvDKAHZ.png

Aliases小結

原則上就是當兩個以上相同的field name時,可以自己為它命一個別名,以上就是筆者認為比較有可能遇到的情境之一,當然以上的做法當然可以把所有的值存在靠瀏覽器cache起來在各個頁面之間傳遞資料,不過這不是我們要討論的事情,也不會是最理想的做法.

Fragments

why use?

雖然Aliases可以幫我們解決掉重複query重一個field時的情況,但如果是以下狀況可讀性就越來越差了

query{
  meal1: meal(id:"58811ae5-1471-4366-844b-2886b3abccf1"){
    id
    itemName
    price
    unit
    specialOffer
    isStopSelling
  }
  meal2: meal(id:"19506d93-d6dc-486e-8b08-5c6045f8d348"){
    id
    itemName
    price
    unit
    specialOffer
    isStopSelling
  }
  meal3: meal(id:"f96d8779-1981-400a-b5b0-45ef36b7f6e8"){
    id
    itemName
    price
    unit
    specialOffer
    isStopSelling
  }
  meal4: meal(id:"251188ae-bc8c-4f37-b809-1884f0f6283e"){
    id
    itemName
    price
    unit
    specialOffer
    isStopSelling
  }
}

基本上有兩個很大的問題,第一個為原則上我要取得的itemNmae,price諸如此類的東西是一樣的,但我卻要重複的寫一樣的內容,第二個為假設我真的有特殊狀況為我只有最後一筆要有isStopSelling,也會變得非常的不易讀,因此我們可以使用Fragments來幫我們完成,以下為範例

# Write your query or mutation here
query{
  meal1: meal(id:"58811ae5-1471-4366-844b-2886b3abccf1"){
    ...mealData
  }
  meal2: meal(id:"19506d93-d6dc-486e-8b08-5c6045f8d348"){
    ...mealData
  }
  meal3: meal(id:"f96d8779-1981-400a-b5b0-45ef36b7f6e8"){
    ...mealData
  }
  meal4: meal(id:"251188ae-bc8c-4f37-b809-1884f0f6283e"){
   ...mealData
    isStopSelling
  }
}

fragment mealData on Meal {
  id
  itemName
  price
}

可以看到把共同需要回傳的field names用...mealData表示後在最下面只要透過fragment就可以完成了,此外,最後一筆才有isStopSelling也可以比較明確的看得出來
https://ithelp.ithome.com.tw/upload/images/20230222/20144476hliZ0OFjSG.png

Fragments小結

當你使用Aliases到一定程度後,可能會覺得code有點不好維護,這個時候就可以透過Fragments,甚至也可以處理一些field names不一的情況

Operation Name

why use?

筆者的經驗是前端在使用api時,很常會同時query多個資料,這點對於維護者或是任何人看起來都會非常的難受,如下圖
https://ithelp.ithome.com.tw/upload/images/20230222/20144476Ss3SJpV8KS.png
雖然我們可以從上述語法中了解,它同時查了meal和user但這件事情本身非常的不直觀,因此我們需要幫這個query命一個名稱
https://ithelp.ithome.com.tw/upload/images/20230222/20144476UCP9AUu3TL.png
會發現得到的結果居然完全一樣,那為什麼要這樣做?
雖然結果是一樣的,但不同的是在讀code時看到mealAndUser就可以很明確的知道這邊在做什麼事情

Operation Name小結

筆者覺得它完全是偏向維護的概念來使用的,不像Framents和Aliases,是真的在某些時候你使用了它時,是以讓程式更乾淨或是增加前端效能為目的的去使用

以上若有錯誤,還請不吝指教.謝謝

下一篇 GraphQL-Variables, Directives, Enumeration Types


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言