2020-08-14

GraphQL その1 GitHubのAPI叩いて入門編

このブログの最初の記事で入門したいと言いつつもずっとスルーしていたGraphQLへ入門したので、簡単に記事にまとめておく
ちなみに読みは「ぐらふぃくる」らしい

GraphQLとは?

なにはともあれまずは公式ページへ行くと、でかでかとこう書いてある

A query language for your API (訳: APIのためのクエリ言語)

僕はクエリ言語といえばSQLを真っ先に想像しますが、どうもそういった類の言語らしい

公式ではさらにGraphQLの特徴として以下の3つを挙げている

  • Ask for what you need, get exactly that (訳: 必要なものを正確に得る)

GraphQLのクエリをAPIサーバーへ送信して、必要なものを正確に取得できると書いてある
そして常に予測可能なレスポンスを返すとも書かれている

公式ページにクエリの例も書かれていて

↓クエリ
{
  hero {
    name
  }
}

↓レスポンス
{
  "hero": {
    "name": "Luke Skywalker"
  }
}

確かにクエリから返ってくるレスポンスが確実に予想できるし、欲しいフィールドだけを取得できる

RESTでもAPIの仕様は決まっているので、GET /users を叩いたら「ユーザー一覧が返ってくるはず」と予想できるし、フィールドの内容も叩く前に事前にわかる
ただ、レスポンスに含まれるフィールドは全て決まっているので、不要なフィールドも受け取らなければならない

  • Get many resources in a single request (訳: 1つのリクエストで多くのリソースを得る)

これは公式のアニメーションを見てもらった方がわかりやすいと思う

↓クエリ
{
  hero {
    name
    friends {
      name
    }
  }
}

↓レスポンス
{
  "hero": {
    "name": "Luke Skywalker",
    "friends": [
      { "name": "R2-D2" },
      { "name": "Han Solo" },
      ...
    ]
  }
}

みたいに1リクエストで関連データも取得できるということらしい

  • Describe what’s possible with a type system (訳: 型を記述できる)

GraphQLでは取得したいフィールドを指定してクエリを投げるが、そのフィールドには型が決まっていることが特徴の一つらしい
ということは、GraphQLのAPIサーバーから提供されるデータの型は常に定まっているので、それを受け取って利用する側のアプリケーションも型を使って安全に構築することができるということですね

RESTとGraphQLの違い

  • ↑に書いた通り、型があったり、フィールドがフレキシブルであること(RESTはエンドポイント毎に決まったレスポンスが返るので、フレキシブルではない)
  • GraphQLはエンドポイントが1つだけ(RESTでは必要な分だけエンドポイントを用意する)
  • GraphQLへのリクエストは必ずPOSTで行われる(RESTではGETなども使用する)

のあたりが大きな違いだろうか

GitHubが用意しているAPIを叩いて基本を学ぶ

こっから叩けるらしいので、利用させていただく

画面右にある Docs をクリックすると、APIのドキュメントを見ることができる

1

ではまずは最初に書かれている下記クエリを、ドキュメントと合わせて見ていく

query { 
  viewer { 
    login
  }
}

まず ルートにある query は、

A GraphQL schema provides a root type for each kind of operation.

とあるように、操作の種類ごとにルートタイプを提供するらしい
ドキュメントを見ると querymutation を指定できるっぽいので、その一角
これは省略可能なので、書かなくても問題ない

2

viewer の説明は以下のようになっている

viewer: User!
  The currently authenticated user.

見るからに User! は型っぽいので、公式のスキーマとタイプのページを見てみると
viewerはUser型であり、!はフィールドがnull不可を意味する
という認識でよさそうだ

ということで viewer をクエリすると、必ずなんらかの値を返してくることがわかる

では最後に login フィールドを見ると
(viewerの型はUserなので、Userのドキュメントを見れば良い)

login: String!
  The username used to login.

文字列であり、必ず値が返ってくることがわかる

せっかくなので、どんなリクエストを投げているのかブラウザの検証ツールで見てみる

3

↑でも書いた通り、どんなクエリを投げても、特定のエントリポイントへPOSTでリクエストが行われている

下の方にスクロールすると、 Request payload というものがあるが、これは一体なんだろうか?
(webを支える技術でも見たことない気がする)

4

query にはめっちゃ長い文字列↓が入っているが、なんだかんだ送信したクエリが入っているだけ(#はおそらくコメントだろう)

 query: "# Type queries into this side of the screen, and you will ↵# see intelligent typeaheads aware of the current GraphQL type schema, ↵# live syntax, and validation errors highlighted within the text.↵↵# We'll get you started with a simple query showing your username!↵query { ↵  viewer { ↵    login↵  }↵}"

variables はクエリを入力するフォームのすぐ下にある QUERY VARIABLES の内容っぽい

payload でググって出てきた MDNを見てみると

HTTP メッセージの開始行と HTTP ヘッダーは、まとめてリクエストのヘッドとして知られています。一方、ペイロードは本文として知られています。

ということなので、リクエストbodyという理解でいいんだろうか?
(↑のMDNのページにある画像もbodyって書いてあるし...)

ググったらここでめっちゃ議論されているけど、bodyとpayloadは同じ派と違うものである派両方いてよーわからん
でも同じものと捉えていたとしても大きな問題にはならなさそうなので、ひとまず同じもんだと思っておく

簡単だけどざっくり何なのかを把握したので、次回より詳しく言語仕様を見ていくことにする