2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Next.js】ApolloClientを使ってGraphQL APIデータを取得しよう!

Last updated at Posted at 2022-09-30

GraphQLサーバーからのデータフェッチ方法はSSGやサーバー側が用意したSDKなど多様にありますが、 最近使ったApollo Clientが使いやすかったので紹介します。
なお、実装例はNext.jsを使用してGitHub GraphQL APIからデータフェッチを行います。

Apollo Clientがおすすめな理由

公式サイトに色々理由が書いてありますが、この中で一番の理由はuseQueryフックがデフォルトで用意されていることかと思います。
これによって、自分でデータフェッチ用のコードを書く必要性がなくなり、従来より短いコードで実装ができるようになります。
なお、useQueryは多機能らしいのですが、自分はまだそこまで使いこなしていないのでご了承ください。

環境

  • Next.js
  • GitHub GraphQL APIでデータを取得するための準備が出来ている
    (GitHubトークンを取得し、エクスプローラーなどでクエリーが作成できている)
    ※GraphQL APIの使い方は割愛します。

実装その1 パッケージのインストール

1から5までは公式サイトのステップ2~5をそのまま引用したものです。実装の基本は公式ドキュメントなので、まずは公式ドキュメントを見ながら手を動かしてみて、つまったら参考サイトを活用することをお勧めします。私も心掛けています。現実は厳しいですが・・・涙
インストールに関してはステップ2のとおり

npm install @apollo/client graphql

または

yarn add @apollo/client graphql

をインストールしてください。

実装その2 ApolloClientインスタンスの初期化(クライアント情報の作成)

ApolloClientのインスタンスを新たに生成します。
uriはエンドポイントを指定します。GitHub GraphQL APIのエンドポイントはこちら

公式の例にはありませんが、インスタンス作成の際にユーザーを認証する情報が必要になります。
GitHub GraphQL APIの場合だとheadersにアクセストークン情報が必要なので、それを追記しています。
なお、アクセストークン情報の直書きは厳禁です。環境変数を使いましょう。

ファイルはライブラリ関係だとlibが使われることが多いので、以下のパスに作成しました。
/src/lib/apollo/apolloClient.ts

export const apolloClient = new ApolloClient({
  cache: new InMemoryCache(),
  headers: { authorization: `Bearer ${process.env.GH_TOKEN}` },
  uri: "https://api.github.com/graphql",
});

実装その3 クライアント情報をセットする。

その2で作成したクライアント情報をインポートしてReact側に渡します。
まずは_app.tsx(jsx)内に作成したクライアント情報(その2で作成したapolloClient)とApolloProviderをインポートします。
ApolloProviderはコンポーネントとして、<Component {...pageProps} />をラップする形で設置してください。
あとは、インポートしたクライアント情報を引数としてApolloProviderコンポーネントに渡せばOKです。
以下が_app.tsx(jsx)の例です。

import "../styles/globals.css";
import type { AppProps } from "next/app";
import { ApolloProvider } from "@apollo/client";
import { apolloClient } from "src/lib/apollo/apolloClient";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ApolloProvider client={apolloClient}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

export default MyApp;

この作業により、どのページからもデータをフェッチすることができるようになりました。すごいですね!

実装その4 useQueryを使ってデータフェッチを行う

その3でどのページからもデータをフェッチすることができるとお伝えしましたが、方法はuseQueryを使用します。
まずはNext.jsのpages配下に任意のページ用ファイルを作成してください、

次に、そのページ内にエンドポイントからデータフェッチする際のクエリ情報を定義します。
内容は、5件分のリポジトリを最新の更新順に取得するもので、作成日や更新日、リポジトリのURL情報などがとれるように設定しています。

const GET_REPOSITORIES = gql`
  query UseGitHubInfo {
    user(login: "topaoad") {
      name
      url
      repositories(last: 5, orderBy: { field: UPDATED_AT, direction: ASC }) {
        totalCount
        nodes {
          name
          description
          createdAt
          updatedAt
          url
          forkCount
          stargazerCount
          languages(orderBy: { field: SIZE, direction: DESC }, last: 10) {
            totalCount
            totalSize
            edges {
              node {
                id
                name
                color
              }
              size
            }
          }
        }
      }
    }
  }
`;

もしクエリの作成がまだでしたら、以下のページで作成してください。

次に、先ほど定義したクエリ情報を使ってuseQueryでフェッチします。
ページのメインコンポーネント内のreturn文の前に以下のように書いてください。
すると、先ほどのクエリ情報を元にGitHub GraphQL APIからデータを取得し、data内に格納されます。
あとは、dataで取得したデータを使って、map関数などを用いて好き好きに実装をしてください!!

const Apollotest: NextPage = () => {
  const { data, error, loading } = useQuery<UseGitHubInfoQuery>(
    GET_REPOSITORIES
  );

  return 
};

export default Apollotest;

実装その5 取得したデータに型定義を行う。

公式サイトの案内はここまでですが、実はもう一つやりたいことがあります。
それは、「取得したデータの自動型付け」です。
その4のuseQueryに<UseGitHubInfoQuery>というジェネリック型の型定義あるのにお気づきですか?
これは、GraphQL Code Generatorを用いて型定義ファイルを作成した際のものを引用しているのです。

詳しい作成方法はこちらの記事で紹介してますので、よければご覧ください。
引用したファイルについて簡単に説明しますと、型定義ファイル作成の際に標準で設定されているプラグイン
「Tpescript-operations」により、クエリと対になる型定義が自動で作成されます。
これを活用しているのです。
なお、typeの型定義名は「自分がつけたクエリ名+Query」となります。
私が命名したクエリ名がUseGitHubInfoだったので、下記例はUseGitHubInfoQueryとなります。

export type UseGitHubInfoQuery = {
  __typename?: "Query";
  user?: {
    __typename?: "User";
    name?: string | null;
    url: any;
    repositories: {
      __typename?: "RepositoryConnection";
      totalCount: number;
      nodes?: Array<{
        __typename?: "Repository";
        name: string;
        description?: string | null;
        createdAt: any;
        updatedAt: any;
        url: any;
        forkCount: number;
        stargazerCount: number;
        languages?: {
          __typename?: "LanguageConnection";
          totalCount: number;
          totalSize: number;
          edges?: Array<{
            __typename?: "LanguageEdge";
            size: number;
            node: {
              __typename?: "Language";
              id: string;
              name: string;
              color?: string | null;
            };
          } | null> | null;
        } | null;
      } | null> | null;
    };
  } | null;
};

ちゃんと型があたっているか、試しにdataの上にマウスをホバーして確認します。
すると、ちゃんとあたっていることが確認できます!
スクリーンショット (104).png

まとめ

公式サイトに沿った基本的な説明でしたが、最後にプラスアルファで自動型付けの説明もさせていただきました。
自分もまだまだ応用が効かずにハマることが多々ありますが、精一杯概念の理解に努めることがスキルアップには必要不可欠だと思います。
もしご意見がありましたら、遠慮なくお申し付けください。
TwitterのDMなども大歓迎です!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?