【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/

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

```cmd
yarn add node-fetch graphql @apollo/client 
```

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

```javascript
"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();

```

#実行結果一部抜粋

```JSON
{
  "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クエリを実行したい場合には是非参考にしてみてください:cat2: