【Node.js】ApolloClientを使用してサーバーサイドからGraphQLを簡単実行


はじめに

Node.jsでGraphQLを使用するプログラムを書く機会があったのですが、フロントからではなくサーバーサイドから使用する手法を調べるのに少し時間がかかったので記事にしておきます。

AppoloClientとは

GraphQLサーバーと通信するためのライブラリです。
この記事は簡単にGraphQLのクエリを実行することに焦点を置いているため詳しくは紹介しませんが、多機能なライブラリでLoadingやErrorなどの通信状態を自動的にハンドリングしてくれたり、取得結果をキャッシュとして保持したりすることもできます。

実践!

実際にNode.jsのコードからGraphQLを実行しましょう。

事前準備

※Nodejsはインストール済みとします。
以下手順では動作確認のサンプルのためにGitHub GraphQL APIを使用します。
(GitHubのリポジトリやIssueの情報をGraphQLで取得するAPI)
使用するにはトークンが必要なため、事前に以下ページからGenerate new tokenボタンを押してトークン発行しておいてください。
https://github.com/settings/tokens/

また、使用するライブラリはソースの実行前に事前に以下コマンドでインストールしておいてください。

yarn add node-fetch graphql @apollo/client 

ソースコード

※定数tokenの設定内容は事前準備で作成したトークンに置き換えてください

"use strict";

global.fetch = require("node-fetch");
const { ApolloClient, InMemoryCache, gql } = require("@apollo/client/core");
const token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

// 自分のリポジトリを取得するクエリ
const searchQuery = gql`
  query repositories($number_of_repos: Int!) {
    viewer {
      repositories(last: $number_of_repos) {
        nodes {
          name
        }
      }
    }
  }
`;

// https://github.com/octocat/Hello-World/issues/349 のイシューにリアクションを付けるクエリ
const mutationQuery = gql`
  mutation AddReactionToIssue {
    addReaction(
      input: { subjectId: "MDU6SXNzdWUyMzEzOTE1NTE=", content: HOORAY }
    ) {
      reaction {
        content
      }
      subject {
        id
      }
    }
  }
`;

// GraphQL クライアントを生成
const apolloClient = new ApolloClient({
  uri: "https://api.github.com/graphql",
  headers: { authorization: `Bearer ${token}` },
  cache: new InMemoryCache(),
});

// searchQueryを実行する関数
async function search() {
  const searchResult = await apolloClient
    .query({ query: searchQuery, variables: { number_of_repos: 3 } }) //取得するリポジトリの数を設定
    .then((result) => {
      return result;
    })
    .catch((error) => {
      console.log(error);
    });
  console.log(JSON.stringify(searchResult, undefined, 2));
}

// mutationQueryを実行する関数
async function mutation() {
  const mutationResult = await apolloClient
    .mutate({ mutation: mutationQuery })
    .then((result) => {
      return result;
    })
    .catch((error) => {
      console.log(error);
    });
  console.log(JSON.stringify(mutationResult, undefined, 2));
}

search();
mutation();

実行結果一部抜粋

{
  "data": {
    "viewer": {
      "__typename": "User",
      "repositories": {
        "__typename": "RepositoryConnection",
        "nodes": [
          {
            "__typename": "Repository",
            "name": "Repository1"
          },
          {
            "__typename": "Repository",
            "name": "Repository2"
          },
          {
            "__typename": "Repository",
            "name": "Repository3"
          }
        ]
      }
    }
  }
}
{
  "data": {
    "addReaction": {
      "reaction": {
        "content": "HOORAY",
        "__typename": "Reaction"
      },
      "subject": {
        "id": "MDU6SXNzdWUyMzEzOTE1NTE=",
        "__typename": "Issue"
      },
      "__typename": "AddReactionPayload"
    }
  }
}

1つ目のdataがqueryで取得したリポジトリの情報です。
2つ目のdataはmutationで行ったIssueへのリアクションの結果です。
ソース実行後以下のIssueを確認するとあなたのアカウントでリアクションがついていることが確認できます。
※GitHub公式が作成したリアクションテスト用のIssueです。
https://github.com/octocat/Hello-World/issues/349

 
 
 
以上です。
シークレットキーをフロントに置きたくない等の理由でサーバーサイドからGraphQLクエリを実行したい場合には是非参考にしてみてください