GraphQL を使ってみる

GraphQL が初めてリリースされたとき、GraphQL は REST を代替するものと思われていました。
REST APIの問題点として、1度の GET リクエストで過剰に情報を取得してしまう点があります。

GraphQL では欲しいデータを受け取れるようにクエリを作成し、望んだ構造のレスポンスを受け取ることができます。

同様に、REST API のケースでは一度では必要な情報を取り切れないケースもあります。
たとえば、ある人物が書いた書籍名がほしいとします。

<code>/api/people/1</code>でその人物の詳細情報が返ってきます。

詳細情報にはその人物が書いた書籍の ID が含まれています。
書籍名を取得するためには、その ID から 書籍 を取得する API を叩かなければいけません。

結果として、 REST API は複数ものリクエストを送らなければいけなくなり、本当に必要な情報を取得するまでたくさんのリクエストのやり取りを行う羽目になります。

GraphQL の問い合わせ

公開API に対してクエリを送信してみることができます。

GitHubのAPI
https://docs.github.com/en/graphql/overview/explorer

スター・ウォーズのAPI
https://swapi.dev/

スノートゥースのAPI
https://snowtooth.moonhighway.com/

GraphQL のクエリ

データを取得するときは query オペレーションを使用します。

query trailsAccessedByJazzCat {
  Lift(id:"jazz-cat") {
    capacity
    trailAccess {
      name
      difficulty
    }
  }
}

 

fragment を利用して冗長な記述をまとめる

fragment liftInfo on Lift {
  name
  status
  capacity
  night
  elevationGain
}

query {
  Lift(id: "jazz-cat") {
    ...liftInfo
    trailAccess {
      name
      difficulty
    }
  }
  Trail(id: "river-run") {
    name
    difficulty
    accessedByLifts {
      ...liftInfo
    }
  }
}

 

ミューテーション

GraphQL の書き込み操作はミューテーションが担当します。

mutation createSong {
  addSong(title: "No Scrubs", numberOne: true, performerName: "TLC") {
    id
    title
    numberOne
  }
} 

mutation の引数に与えた値で新たな値を作成(create)し、 { } の中にレスポンスとして欲しいフィールドを記載します。 

サブスクリプション

サブスクリプションとは、サーバーが更新されるたびにクライアントでその情報をリアルタイムに受け取りたい場合に利用するオペレーションです。

http://snowtooth.moonhighway.com/ を開き、以下のような構文でサーバーの変更を監視します。

subscription {
  liftStatusChange {
    name
    capacity
    status
  }
}

 

別のブラウザを開いて mutation でデータを変更してみます。

mutation closeLift {
  setLiftStatus(id: "astra-express" status: HOLD) {
    name
    status
  }
}

 

すると、subscription していた方の GraphQL に結果がプッシュされます。

イントロスペクション

イントロスペクションは API スキーマの詳細を取得できる機能です。

以下のようにクエリで __schema を指定することでスキーマを取得できます。

query {
  __schema {
    types {
      name
      description
    }
  }
}