GitHub GraphQL APIで任意の情報を一発で取得する


この記事は Akatsuki Advent Calendar 2018 の 10 日目の記事です。

きっかけ

GitHub上の任意の情報を抽出する際に、スクリプトを組んでREST APIを何度も実行していたのですが、GraphQL APIならシンプルに欲しい情報を取得できるとのことだったので、実際に触ってみた内容を書きます。
今回はこんな感じで使えるのかーというのを掴んでもらうために、使ってみるを中心に進めていきます。

GraphQL APIの使い方

GitHub GraphQL APIはExplorerで簡単に実行できます。
https://developer.github.com/v4/explorer/

画面はこのようになっており、左側に実行したいGraphQLを記入し、実行するだけです。

動かしてみる

今回は、自分のプロジェクトに関連するチームが閲覧できるリポジトリの一覧を取得する というクエリを書いてみます。

query {
  organization(login: "組織のアカウント名"){
    name,
    login,
    teams(query: "検索ワード",first: 100){
      totalCount,
      edges{
        node{
          name,
          repositories(first: 100){
            totalCount,
            edges{
              node{
                nameWithOwner
              }
            }
          }
        }
      }
    }
  }
}


これを実行すると、このようなデータが返ってきます。

{
  "data": {
    "organization": {
      "name": "組織名",
      "login": "組織のアカウント名",
      "teams": {
        "totalCount": 9,
        "edges": [
          {
            "node": {
              "name": "チーム名",
              "repositories": {
                "totalCount": 32,
                "edges": [
                  {
                    "node": {
                      "nameWithOwner": "所有者/リポジトリ名"
                    }
                  },
                  {
                    "node": {
                      "nameWithOwner": "所有者/リポジトリ名"
                    }
                  }
          ・
          (長いので省略)
          ・
                ]
              }
            }
          },
          ・
          (長いので省略)
          ・
        ]
      }
    }
  }
}

このような形で、簡単に欲しい情報だけを取得することができます。

ちなみに、他にどのようなConnectionやFieldがあるか確認したい場合は、
UI上でカーソルを合わせるとリファレンスを参照できるので便利です。

クエリの解説

query {
GraphQLには「Query」と「Mutation」という2つの型があります。
「Query」がデータの取得、「Mutation」がデータの変更になっています。
今回はデータを取得したいので、queryを使用します。

organization(login: "組織のアカウント名"){
ここでは組織のオブジェクトを取得します。
引数のloginが必須なので、組織のアカウント名を入れます。

teams(query: "検索ワード",first: 100){
組織に存在するチームのオブジェクトを取得します。
queryでチーム名に関連する文字列を入れて絞ることができます。
自分たちのプロジェクトではチームの命名規則が決まっているので、そこが引っかかるように検索ワードを入れました。
firstはリストの最初からn件を表示します。100までしか指定できないので、超える場合はafter(指定されたcursorの後に来るリスト内の要素を返す)を使用して表示する範囲を変更して対応します。

edges{
teamsは複数のチームのデータを持っているので、それぞれのデータにアクセスするためにはedgeを介してアクセスします。
edgeはcursorなどのnodeを識別する情報を持っています。

node{
チームのデータ(nameなどのチーム自体の情報)が含まれています。

まとめ

このように使ってみると一つのクエリで欲しい情報に到達することができ、explorerの使い勝手もかなりよかったです。
またGraphQLというものに初めて触れましたが、シンプルに無駄のないAPIリクエストを実現できるのは魅力的だなと感じました。
ゲームを作る上でも、仕様変更によるAPIの修正は発生しており、その都度対応コストもかかっていたので、この辺りを解消できたりもするのかなーとか考えつつ、GraphQLの理解をもう少し深めたいなと思いました。