🚀

Reactとapollo-boostでGitHub GraphQL APIを爆速で叩く

2021/01/04に公開

事前準備

  • GitHub Tokenの発行

手順

アプリ作成

yarn create react-app react-apollo-boost --template typescript

パッケージインストール

yarn add apollo-boost graphql graphql-tag

環境変数追加

$ echo 'REACT_APP_GITHUB_TOKEN={作成したGitHub Token}' > .env

(Next.jsの場合は NEXT_PUBLIC_GITHUB_TOKEN とします。)

src/App.tsx

コード整理

まずは不必要なコードを削除して綺麗にします。

import React from 'react';

function App() {
  return (
    <div className="App">
    </div>
  );
}

export default App;

モジュールのインポート

import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';

クエリ

このサンプルでは公開リポジトリの Name URL Description を取得します。

const GET_REPOSITORY = gql`
  query {
    viewer {
      repositories(
        first: 3
        privacy: PUBLIC
        isFork: false
        orderBy: { field: CREATED_AT, direction: DESC }
      ) {
        nodes {
          name
          url
          description
        }
      }
    }
  }
`;

FYI: GitHub API ドキュメント
https://docs.github.com/ja/free-pro-team@latest/graphql/reference

GitHub APIのレスポンスの型定義

レスポンスの型定義も手動で定義します。

type Repository = {
  name: string;
  url: string;
  description: string;
}

Apollo Client

const client = new ApolloClient({
  uri: 'https://api.github.com/graphql',
  request: (operation) => {
    operation.setContext({
      headers: {
        authorization: `Bearer ${process.env.REACT_APP_GITHUB_TOKEN}`
      }
    });
  }
});

データ取得

const fetch = async () => {
  const { data } = await client.query({
    query: GET_REPOSITORY
  });
};

Hooks経由で表示

function App() {
  const [repositories, setRepositories] = React.useState<Repository[]>([]);

  const fetch = async () => {
    const { data } = await client.query({
      query: GET_REPOSITORY
    });
    setRepositories(data.viewer.repositories.nodes);
  };

  React.useEffect(() => {
    fetch();
  }, []);

  return (
    <div className="App">
      <div>
        {repositories.map((repository: Repository) => {
          return (
            <div key={repository.name}>
              <b>Repository: {repository.name}</b>
              <p>URL: {repository.url}</p>
              <p>Description: {repository.description || '-'}</p>
            </div>)
        })}
      </div>
    </div>
  );
}

全体

src/App.tsx
import React from 'react';
import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';

type Repository = {
  name: string;
  url: string;
  description: string;
}

const GET_REPOSITORY = gql`
  query {
    viewer {
      repositories(
        first: 3
        privacy: PUBLIC
        isFork: false
        orderBy: { field: CREATED_AT, direction: DESC }
      ) {
        nodes {
          name
          url
          description
        }
      }
    }
  }
`;

const client = new ApolloClient({
  uri: 'https://api.github.com/graphql',
  request: (operation) => {
    operation.setContext({
      headers: {
        authorization: `Bearer ${process.env.REACT_APP_GITHUB_TOKEN}`
      }
    });
  }
});

function App() {
  const [repositories, setRepositories] = React.useState<Repository[]>([]);

  const fetch = async () => {
    const { data } = await client.query({
      query: GET_REPOSITORY
    });
    setRepositories(data.viewer.repositories.nodes);
  };

  React.useEffect(() => {
    fetch();
  }, []);


  return (
    <div className="App">
      <div>
        {repositories.map((repository: Repository) => {
          return (
            <div style={style} key={repository.name}>
              <b>Repository: {repository.name}</b>
              <p>URL: {repository.url}</p>
              <p>Description: {repository.description}</p>
            </div>)
        })}
      </div>
    </div>
  );
}

const style = { 
  margin: '8px auto',
  padding: '8px',
  border: '1px solid #000',
  width: '500px'
}

export default App;

結果

最後に

React + apollo-boost の使用例としては、ポートフォリオなどでリポジトリなどを表示させたい場合や、
一部だけGraphQLを使用したい場合などに有効です。

apollo-boost はその名の通り素早く簡単にApollo Clientを使いはじめることができますが、
apollo-client のラッパーという位置付けもあり、カスタマイズしづらくなっています

実際にプロダクションで使用する場合や、RESTではなくGraphQLをメインとしている場合は apollo-client を使用するようにしましょう。
マイグレーションガイドも存在します。
https://www.apollographql.com/docs/react/v2/migrating/boost-migration/

Discussion