はじめに
以下のゴールを達成するため、本日はついに、Next.jsとHasuraを連携してデータを画面に出すところまでやります。
特に今回は、Next.jsでApollo Clientを使ってSSR(SSG)する仕組みの部分を見て行くと思います。
Hasuraにあるデータやエンドポイントは既に用意
最終的なゴール
以下のような構成のアプリを作ることです。
目的
- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上
Apollo Clientの準備
以下の2つを連携させていきます。
- Frontend: Next.jsとApolloClient
- Backend: HasuraのGraphqlサーバ
具体的な方法はここからパクります。
Next.js公式の実例集ですね。
ここから必要な部分だけ抜き取っていきます。
具体的には👇ここら辺ですね。
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: new HttpLink({
uri: 'https://nextjs-graphql-with-prisma-simple.vercel.app/api', // Server URL (must be absolute)
credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers`
}),
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
allPosts: concatPagination(),
},
},
},
}),
})
}
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient()
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// gets hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract()
// Merge the existing cache into data passed from getStaticProps/getServerSideProps
const data = merge(initialState, existingCache, {
// combine arrays using object equality (like in sets)
arrayMerge: (destinationArray, sourceArray) => [
...sourceArray,
...destinationArray.filter((d) =>
sourceArray.every((s) => !isEqual(d, s))
),
],
})
// Restore the cache with the merged data
_apolloClient.cache.restore(data)
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient
return _apolloClient
}
注目するポイントはまずここ
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient
Next.jsは、SSR, SSG, ISRのようなbackendで実行される処理と、クライアントで実行される処理が混在しています。
タイトルにガッツリ「SSR, SSG, ISRの概要理解」とか書いておきながらアレですが、下記の記事が勉強になります。
そうすることで、Next.jsは、多様なアプリケーションに対応するために、HTMLを生成する方法を複数用意しています。
(上記とほぼ同じこと言ってます。)
HTMLはどこで生成して、どうやって受け取るかの話ですが、Apollo Clientで切り分けられています。
特に、まずここ
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
サーバーサイドで実行される、
- 「ビルド時」にデータを取得する
getStaticProps
- 「ビルド時」にデータを取得する(Dynamic Routing を作る)
getStaticPaths
のところでは、Apollo Clientを使う場合は、毎回新しいApollo Clientインスタンスが作成されます。
次にここ
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient
クライアントで実行されるクエリの発行などは、最初に1回だけapolloClient
を作れば使い回されます。
このサーバーサイドの処理と、クライアントサイドの処理の切り分けが適切にされていないと
アプリケーション実行に、SSGやISRなどの実行が思った通りに行かないことがあると思います。
だから結構大事な処理になるので覚えておきましょう!
では、次回以降で具体的な実装方法を見ていきましょう。
アウトプット100本ノック実施中