GraphQLを調べている。こういったものを使ってるのには身近なのだとGitHubとかがある。 前々からHoppscotchという自分が使っているHTTPクライアントを使って試してなんとなしにやってたのだが、 よう~やくちょっと分かってきてはいる。簡単に見えて結構とっつきにくい。 単一エンドポイントで複数の情報が取れてドキュメント化も楽、というのがメリットなのだと理解している(今のところ)。 PubSubはまだ分かっていない。
定番らしいSnowtoothというのを使って叩いてみる。
GraphQLはschema
という暗黙のデータ型のトップレベルの概念があり、
直下にQuery
とMutation
という型を持つquery
およびmutation
が属している。よってquery
とmutation
というキーワードを軸に考えていくのが基本、なのだと思っている。
まず、query
。基本はこれ。
{
allLifts(status: OPEN) {
id
name
status
}
}
これは厳密にはquery
キーワードの糖衣構文と理解してる。
query {
allLifts(status: OPEN) {
id
name
status
}
}
さらに言えば、このようになる。クエリは任意の名前をつけることが出来る。 GraphQLの公式ドキュメントだと一応説明があるんだけど、唐突に出てくるから、こういうのを理解するのに苦労した。引き算で教えてくれたほうが僕は分かりやすかったかな。だから、苦労している人はここをまず抑えると良いのだと思った。確かに省略記法が特徴なんだけれども。
query GetOpenLifts {
allLifts(status: OPEN) {
id
name
status
}
}
こうすると、外部から引数を与えることができるようになる。
{
"status": "OPEN"
}
私を困惑させたのはallLifts()
の変数が後置になっていることである。
癖でタイプヒントと思ってしまうわけだが、ここでの文法的意味はキーワード引数の指定である。
query GetOpenLifts($status: LiftStatus) {
allLifts(status: $status) {
id
name
status
}
}
jsonでallLifts
ではなくlifts
と記載して返してほしければ次のようにする
query {
lifts: allLifts(status: OPEN) {
id
name
status
}
}
さらに言えば、以下はスプレッド展開的な構文で書く場合である。これは... on Lift
を省略した時と結果は同じである
query {
allLifts(status: OPEN) {
... on Lift {
id
name
status
}
}
}
この機能は本来fragment
と呼ばれるものであり、いわゆる取りたい型だけ分離して定義することが出来る
fragment LiftFragment on Lift {
id
name
status
}
query {
allLifts(status: OPEN) {
...LiftFragment
}
}
mutation
はCRUDで言うCUDにあたる。この時のsetLiftStatus
のブロックも要は戻り値である。
mutation JazzCatToClosed {
setLiftStatus(id: "jazz-cat", status: CLOSED) {
id
name
status
}
}
引数付きにするならこんな感じ。
{
"id": "jazz-cat",
"status": "OPEN"
}
mutation JazzCatToClosed($id: ID!, $status: LiftStatus!) {
setLiftStatus(id: $id, status: $status) {
id
name
status
}
}
こういったmutationを基本的に想定した型には入力用にinput
というのも定義される場合があって、
端的にはそのまんま入力用の型のことである。要はORMとかの更新用関数でjavascriptに与えるアレの型みたいな感じである。
他には@ディレクティブ
, Union Type
, type
の定義に実装可能なinterface
などの概念がある。
色々とっつきにくい部分もあるが、便利なのは少し理解できる。まだ染み付いてはいない。
サーバ実装の上でも特有の問題がありそう。この点はメルカリのブログが参考になりそうなのでメモっておく。