GraphQLを試してみた
こんにちは。ぬまたです。
約半年ぶりの投稿です。空けすぎました。
最近AppSyncを触る機会があったので、基礎となるGraphQLを学びたいと思います。
目次
GraphQLとは
GraphQLはフロントエンドがサーバのデータをいい感じに取得するためのクエリ言語です(怒られそう)。 ざっと調べる限りは以下のような特徴がありました。
- 読み取りと書き込みが分離している
- エンドポイントが一つ
- データ群の処理結果などをパラメータに追加できる
- Schemaや型を定義する
- 変数やコメントアウトを使うことができる
- キャッシュが比較的容易
実際に使ってみないとわからないので、GitHub APIで試してみます。 GitHubはAPIのバージョン4からGraphQLを導入しています。
参考: - GitHub API v4
検証環境
GitHubのデベロッパーツールを使用します。
GraphQLはエンドポイントをリソースごとに分けずにパラメータで指定します。
GitHubではリクエストを https://api.github.com/graphql
に向け、パラメータにクエリを入れています。
GitHub API を試してみる
ログインしているユーザーのメールアドレス取得
単一のリソースfields
から指定したキーの値を取得できます。
現在ログインしているユーザのメールアドレスを取得してみます。
GitHubは viewer
という fields
にログインユーザー情報が入っています。
クエリ内にパラメータ(email
)を指定して取得することができます。
クエリ
{ viewer { email } }
結果
{ "data": { "viewer": { "email": "nununu.mono@gmail.com" } } }
Dockerの関連トピックを取得
fields
は引数を取ることができます。
GitHubのDockerトピックに関連するトピックを取得してみます。
クエリ
query { topic(name: "docker") { relatedTopics { name } } }
結果
{ "data": { "topic": { "relatedTopics": [ { "name": "docker-container" }, { "name": "jhipster" }, { "name": "docker-image" }, { "name": "database" }, { "name": "ruby" }, { "name": "composer" }, { "name": "nginx" }, { "name": "yii" } ] } } }
relatedTopics
はオブジェクトのリストになっています。
ネストしたオブジェクトのキー(今回は name
)を選択できることが異なる点ですね。
リポジトリ内のPR一覧を取得
nodes
を使ってリスト値と欲しいパラメータを取得することができます。
今回はよく使うDjangoRESTFrameworkのPR一覧とそれぞれのコミット数を調べてみます。
クエリ
query { repository(owner: "encode" name: "django-rest-framework") { pullRequests(last: 5 states: OPEN) { nodes { number title commits { totalCount } } } } }
結果
{ "data": { "repository": { "pullRequests": { "nodes": [ { "number": 6279, "title": "Let SearchFilter subclasses dynamically set search fields", "commits": { "totalCount": 4 } }, { "number": 6282, "title": "Ensure serializer and field validators support both lists and tuples", "commits": { "totalCount": 2 } }, { "number": 6284, "title": "Don't force implement get_queryset", "commits": { "totalCount": 1 } }, { "number": 6286, "title": "permissions must return a boolean to allow &/| operator comparison", "commits": { "totalCount": 3 } }, { "number": 6288, "title": "Fix DjangoObjectPermissionsFilter deprecation note", "commits": { "totalCount": 2 } } ] } } } }
pullRequests
の引数にPRが OPEN
であることと、最新の5つを取得するよう指定しています。
DjangoRESTFrameworkのGitHubをみると正しそうです。
nodes
はPRのリスト値にあたり、その中でPRのNoやコミット数を指定しています。
commits
に totalCount
パラメータが入っているので、データを全て取得せずに総数を把握することができますね。
自分でSchemaを定義する場合はクライアントが欲しい値を自由に追加することができます。
特定条件のリポジトリ数の取得
GraphQLのPaginationを使ってクエリ結果の総数を取得できます。 Pythonで書かれているスター数1000以上のリポジトリが何個あるか調べてみます。
クエリ
query { search(query: "language: Python stars:>1000", type: REPOSITORY) { repositoryCount }
結果
{ "data": { "search": { "repositoryCount": 28 } } }
search
はGitHubで定義されているコネクションです。クエリに加えて読み取り開始位置 after
などを定義できるようになっています。
今回は query
と type
に検索したい条件をして、値に repositoryCount
を取ることでリポジトリ数を取得しています。
search
の引数を変えて、色々な検索をかけられるのはよいですね。
まとめ
今回は読み取りの Query
を中心にGraphQLを試してみました。
GraphQLのメリットはクライアントの負担が減ることなのかなという所感です。
Schemaの定義はクライアントの要求を取り入れつつ、データベース内のモデルの知識が求められそうですね。 その辺りも今後調べたいと思います。