Next.jsからGitHub GraphQL APIを使用

概要

Next.js/TypeScriptのプロジェクトから、GitHubのGraphQL APIにアクセスする方法を簡単にメモします。Next.jsのapiルートからGraphQL Yogaとgraphql-requestを用い方法になります。

詳細は以下を参照。

GraphQLのエクスプローラ

https://docs.github.com/ja/graphql/overview/explorer にて、GitHubアカウントでサインインした上で、次のクエリを入力します。

query {
  viewer {
    login
  }
}

これで次の結果が得られます。

{
  "data": {
    "viewer": {
      "login": "pitang1965"
    }
  }
}

今回は次のクエリを用います。

query MyQuery {
  viewer {
    name
    repositories(last: 5) {
      nodes {
        name
        description
      }
    }
  }
}

このクエリを実行すると先ほどの結果に加えて、5つのリポジトリの名前と説明が出力されます。

インストール

npm i @graphql-yoga/node graphql graphql-request
又は
yarn add @graphql-yoga/node graphql graphql-request
又は
pnpm i @graphql-yoga/node graphql graphql-request

環境変数の設定

GitHub APIのトークンは、GitHubのサイトのSettings → Developer settings → Personal access tokensから取得できます。

// .env.local
GITHUB_BEARER_TOKEN=xxxx

src/pages/api/github.ts

Next.jsのapiルートからgraphql-requestを用いてGitHub GraphQL APIにアクセスし、その結果をGraphQLサーバーであるGraphQL Yogaを使って/api/github として提供します。

import { GraphQLClient, gql } from 'graphql-request';
import { createServer } from '@graphql-yoga/node';

// GitHubからデータを取得

const resolvers = {
  Query: {
    async repositories() {
      const githubEndPoint = 'https://api.github.com/graphql';

      const query = gql`
        {
          viewer {
            name
            repositories(last: 5) {
              nodes {
                name
                description
              }
            }
          }
        }
      `;

      const graphQLClient = new GraphQLClient(githubEndPoint, {
        headers: {
          authorization: `Bearer ${process.env.GITHUB_BEARER_TOKEN}`,
        },
      });

      const data = await graphQLClient.request(query);
      // console.log(JSON.stringify(data.viewer.repositories.nodes, undefined, 2));
      return data.viewer.repositories.nodes;
    },
  },
};

// APIとして値を返す

const typeDefs = /* GraphQL */ `
  type Query {
    repositories: [Repository!]!
  }
  type Repository {
    name: String
    description: String
  }
`;

const server = createServer({
  schema: {
    typeDefs,
    resolvers,
  },
  endpoint: '/api/github',
  // graphiql: false // uncomment to disable GraphiQL
});

export default server;

クライアント側のコード

以下はuseSWRを用いて、/api/githubにアクセスし、5つのリポジトリの名前と説明を表示するコードです。

import useSWR from 'swr';

const fetcher = (query: string) =>
  fetch('/api/github', {
    method: 'POST',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({ query }),
  })
    .then((res) => res.json())
    .then((json) => json.data);

export default function Index() {
  const { data, error } = useSWR(
    `{
      repositories {
        name
        description
      }
    }
    `,
    fetcher
  );

  console.log(data);

  if (error) return <div>Failed to load</div>;
  if (!data) return <div>Loading...</div>;

  const { repositories } = data;

  return (
    <div>
      {repositories.map((repository: any, i: number) => (
        <div key={i}>
          <h1>{repository.name}</h1>
          <p>{repository.description}</p>
        </div>
      ))}
    </div>
  );
}

出力イメージは次です。

pitang-todo
Vite + React + TypeScipt + Supabase による簡単なtodoアプリ

gudid-search
openFDAを用いて企業名からUDI(機器固有識別子)の一覧を得て表で表示。

git_training
next-portfolio
各種APIを用いた自己紹介サイト

qin-team-dev
qinサロンチーム開発