GitHub API v4 GraphQL を叩く

## 概要

[GitHub API v4 GraphQL](https://developer.github.com/v4/) について以下内容を記載しています。

- [v3 REST](https://developer.github.com/v3/)との比較
- なぜ GraphQL なのか？
- GraphQLクエリの例
- 実装例 ( bash )
- 実装例 ( python )

## 参考文献

[v3 REST](https://developer.github.com/v3/)については以下に記事を書いています。

- [GitHub API を 叩く - Qiita](https://qiita.com/loftkun/items/94d4ead8b1dfbc669ffb)
- [GitHubリポジトリのスター数でOSSランキングを作成する - Qiita](https://qiita.com/loftkun/items/5ea5b9577347505729f6)

[v4 GraphQL](https://developer.github.com/v4/)については、[PyFukuoka #7](https://fukuoka-python.connpass.com/event/147318/)に登壇した際の資料もご参照ください。
[Getting Started with Graph Database with Python - Speaker Deck](https://speakerdeck.com/loftkun/getting-started-with-graph-database-with-python)

本記事のサンプルコードは以下に置いています。
[loftkun/github-api-samples: useful scripts for using github api](https://github.com/loftkun/github-api-samples)

## v3 vs v4

     項目      | [GitHub API v3 REST](https://developer.github.com/v3/) | [GitHub API v4 GraphQL](https://developer.github.com/v4/)
-------------- | ------------------------------------------------------ | --------------------------------------------------------
アーキテクチャ    | REST                                                   | GraphQL
認証           | オプション                                             | 必須
認証方式       | Basic or OAuth                                         | 〃
エンドポイント | 複数                                                   | 1つ

## なぜ GraphQL なのか？

[GitHub GraphQL API v4 | GitHub Developer Guide](https://developer.github.com/v4/#why-github-is-using-graphql) に以下の記述があります。

```
GraphQL lets you replace multiple REST requests with a single call to fetch the data you specify.
```

複数のリクエストを1回の呼び出しに置き換えられるメリットがあるようですね。
確かにv3 は PRやIssue毎にエンドポイントが別れていますが、v4 ではエンドポイントは1つで、クエリに取得したいPRやIssueの条件を記載することができます。

## GraphQLクエリの例

[python/python-docs-ja](https://github.com/python/python-docs-ja)のPRとIssueを検索するクエリの例です。

```sql

  query {
    repository(owner:"python", name:"python-docs-ja") {
      pullRequests(first: 2) {
        nodes {
          title
          url
        }
      }
      issues(last:2, states:CLOSED) {
        edges {
          node {
            title
            url
          }
        }
      }
    }
  }
```

## 実装例 ( bash )

[github-api-samples/demo.sh](https://github.com/loftkun/github-api-samples/blob/master/v4/demo.sh) に置いています。

クエリは現在認証済みユーザの情報を表示する例です。

```bash

# OAuthトークン
TOKEN=your_oauth_token

# Endpoint
API=https://api.github.com/graphql

curl -d @- -X POST -H "Authorization: bearer ${TOKEN}" "${API}" << EOF
  {
    "query": "query { viewer { login }}"
  }
EOF
```

## 実装例 ( python )


[github-api-samples/demo.py](https://github.com/loftkun/github-api-samples/blob/master/v4/demo.py)に置いています。

クエリはpythonのスター数の多いリポジトリを検索する例です。

```python

def post(query):
    headers = {"Authorization": "bearer " + token}
    res = requests.post(endpoint, json=query, headers=headers)
    if res.status_code != 200:
      raise Exception("failed : {}".format(res.status_code))
    return res.json()

# query
query={ 'query' : """
  query {
    search(query: "language:python stars:>=1000 sort:stars", type: REPOSITORY, first: 10) {
      edges {
        node {
          ... on Repository {
            nameWithOwner
            url
            createdAt
            description
            stargazers{
              totalCount
            }
          }
        }
      }
    }
  }
  """
}

# post
res = post(test)
print('{}'.format(json.dumps(res)))

```