概要
GitHub API v4 GraphQL について以下内容を記載しています。
- v3 RESTとの比較
- なぜ GraphQL なのか?
- GraphQLクエリの例
- 実装例 ( bash )
- 実装例 ( python )
参考文献
v3 RESTについては以下に記事を書いています。
v4 GraphQLについては、PyFukuoka #7に登壇した際の資料もご参照ください。
Getting Started with Graph Database with Python - Speaker Deck
本記事のサンプルコードは以下に置いています。
loftkun/github-api-samples: useful scripts for using github api
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 に以下の記述があります。
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のPRとIssueを検索するクエリの例です。
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 に置いています。
クエリは現在認証済みユーザの情報を表示する例です。
# 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に置いています。
クエリは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)))