概要
この記事では、Apollo Client
を活用して Next.js
アプリケーションから GraphQL
サーバーのデータを取得・表示するまでの一連の流れを解説します。
全体フロー
まずは、クライアントから GraphQL
サーバーへデータを取得するまでの流れを確認しておきましょう。
実装フロー
1.Apollo 関連の依存関係インストール
まずは Apollo Client
や GraphQL
関連のライブラリをインストールします。
npm install graphql @apollo/client @apollo/server @as-integrations/next
2. GraphQL Code Generator の依存関係インストール
型安全な開発のために、GraphQL Code Generator
を導入します。
これにより、スキーマからTypeScript
型を自動生成できます。
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset @graphql-codegen/typescript @graphql-codegen/typescript-resolvers @graphql-codegen/typescript-document-nodes
3. Codegenの設定
GraphQLスキーマから型を自動生成できるように、Codegenの設定を実施します。
schema: http://${NEXT_PUBLIC_API_DOMAIN}/graphql
documents: './src/**/*.ts'
generates:
./src/app/graphql/generated.ts:
plugins:
- typescript
- typescript-operations
- typed-document-node
config:
scalars:
ISO8601DateTime: string
{
"scripts": {
"codegen": "dotenv -- graphql-codegen --config codegen.yml"
},
}
設定完了後、実行します。
npm run codegen
参考記事
4. Apollo Clientの設定(apollo-client.ts)
GraphQL
サーバーへの接続設定を apollo-client.ts
にまとめます。
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
const httpLink = new HttpLink({
uri: `http://${process.env.NEXT_API_DOMAIN}/graphql`,
credentials: 'include',
fetchOptions: {
mode: 'cors',
}
});
export const apolloClient = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: 'cache-first',
},
mutate: {
fetchPolicy: 'no-cache',
},
},
connectToDevTools: process.env.NODE_ENV !== 'production',
});
クロスサイトのリクエスト時、以下のオプションが含まれていないとCookieが送信されないため指定。
より良い方法があればご教示いただきたいです🙏
credentials: 'include',
fetchOptions: {
mode: 'cors',
}
5. データフェッチャーの実装(fetcher.ts)
GraphQL
クエリを実行するラッパー関数を fetcher.ts
に実装します。
import { apolloClient } from '@/app/graphql/apollo-client';
import { GetPostDocument } from '@/app/graphql';
export async function getPosts(page = 1, perPage = 15) {
const { data } = await apolloClient.query({
query: GetPostsDocument,
variables: { page, perPage },
context: {
headers: {
Cookie: cookieHeader,
},
},
});
return { json: () => Promise.resolve(data.publishedPosts as Post[]) };
};
クロスサイトのリクエスト時、以下のオプションが含まれていないとCookieが送信されないため指定。
より良い方法があればご教示いただきたいです🙏
(ApolloClient
で一括指定したかった...)
context: {
headers: {
Cookie: cookieHeader,
},
},
6. コンポーネントでのデータ取得と表示
最後に、取得したデータをコンポーネント内で表示します。
import { getPosts } from "@/app/(public)/posts/fetcher";
export default async function Home() {
const posts = await getPosts();
const postsJson = await posts.json();
return (
<div>
<h1>記事一覧</h1>
<ul>
{postsJson.map((post) => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.content.substring(0, 50)}...</p>
<a href={`/posts/${post.id}`}>詳細を見る</a>
</li>
))}
</ul>
{postsJson.length === 0 && <p>記事がありません</p>}
</div>
);
}
まとめ
この記事では、Next.js と Apollo Client を用いて GraphQL サーバーからデータを取得し、コンポーネントで表示するまでの流れを解説しました。
- Apollo Clientでの通信設定
- GraphQLクエリの定義と実行
- フェッチャーを挟んだ責務分離