APIのロジックに関する差異
RESTからGraphQLへの移行は、APIロジックの大きな変化を示します。 スタイルとしてのRESTと仕様としてのGraphQLとの違いのために、REST APIの呼び出しをGraphQL APIのクエリに1対1で置き換えることは難しく、しばしば望ましくないことになります。 移行の具体的な例を以下に示しました。
コードを REST API から GraphQL API に移行するには、以下を行います。
- GraphQL仕様のレビュー
- GitHubのGraphQLスキーマのレビュー
- 現在のコードによるGitHub REST APIとのやりとりの考慮
- グローバルノードIDを使ったAPIバージョン間でのオブジェクトの参照
GraphQLによる重要な利点には以下があります。
以下にそれぞれの例を示します。
例:必要なデータ� けを取得
1つのREST API呼び出しで、Organizationのメンバーのリストを取得します。
curl -v http(s)://[hostname]/api/v3/orgs/:org/members 目的がメンバー名とアバターへのリンクの取得� けなのであれば、このRESTのペイロードには過剰なデータが含まれています。 しかし、GraphQLのクエリでは指定した内容� けが返されます。
query { organization(login:"github") { membersWithRole(first: 100) { edges { node { name avatarUrl } } } } } 別の例を考えてみましょう。プルリクエストのリストを取得して、それぞれがマージ可能かをチェックします。 REST APIの呼び出しは、プルリクエストとそのサマリ表現のリストを取得します。
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls プルリクエストがマージ可能かを判断するためには、個別にそれぞれのプルリクエストの詳細な表現(大きなペイロード)を取得し、そのmergeable属性がtrueかfalse下をチェックしなければなりません。
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number GraphQLでは、それぞれのプルリクエストについてnumberとmergeable属性� けを取得できます。
query { repository(owner:"octocat", name:"Hello-World") { pullRequests(last: 10) { edges { node { number mergeable } } } } } 例:入れ子
入れ子になったフィールドにクエリを行うことで、複数のRESTの呼び出しを少数のGraphQLクエリに置き換えられます。 たとえば、プルリクエストをコミット、非レビューコメント、レビューをREST APIを使って取得するには、4つの別々の呼び出しが必要になります。
curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number/commits curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/issues/:number/comments curl -v http(s)://[hostname]/api/v3/repos/:owner/:repo/pulls/:number/reviews GraphQL APIを使えば、入れ子のフィールドを利用して単一のクエリでこのデータを取得できます。
{ repository(owner: "octocat", name: "Hello-World") { pullRequest(number: 1) { commits(first: 10) { edges { node { commit { oid message } } } } comments(first: 10) { edges { node { body author { login } } } } reviews(first: 10) { edges { node { state } } } } } } プルリクエストの番号で変数を置き換えることで、このクエリの力を拡張することもできます。
例:強力な型付け
GraphQLスキーマは強く型付けされており、データの扱いが安全になっています。
IssueもしくはプルリクエストにGraphQLのミューテーションを使ってコメントを追� する例で、間違ってclientMutationIdの値に文字列ではなく整数値を指定してしまったとしましょう。
mutation { addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) { clientMutationId commentEdge { node { body repository { id name nameWithOwner } issue { number } } } } } このクエリを実行すると、この操作に期待される型を指定したエラーが返されます。
{ "data": null, "errors": [ { "message": "Argument 'input' on Field 'addComment' has an invalid value. Expected type 'AddCommentInput!'.", "locations": [ { "line": 3, "column": 3 } ] }, { "message": "Argument 'clientMutationId' on InputObject 'AddCommentInput' has an invalid value. Expected type 'String'.", "locations": [ { "line": 3, "column": 20 } ] } ] } 1234をクオートでラップすれば、この値を整数値から期待されている型である文字列に変換できます。
mutation { addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) { clientMutationId commentEdge { node { body repository { id name nameWithOwner } issue { number } } } } }