Next.jsとHasuraを連携してデータを画面に出すところまでやる（ためのSSR, SSG, ISRの概要理解）...1

## はじめに

以下のゴールを達成するため、本日はついに、Next.jsとHasuraを連携してデータを画面に出すところまでやります。

特に今回は、Next.jsでApollo Clientを使ってSSR(SSG)する仕組みの部分を見て行くと思います。

![イメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/a82854a4-b7ba-4ddd-bf48-c7678f452d7f.jpeg)

Hasuraにあるデータやエンドポイントは既に用意

## 最終的なゴール

以下のような構成のアプリを作ることです。

![スクリーンショット 2021-10-18 17.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/e8a9a2e1-2723-4fec-77ef-be3b9eefdd81.png)

### 目的

- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上

### Apollo Clientの準備

以下の2つを連携させていきます。

- Frontend: Next.jsとApolloClient
- Backend: HasuraのGraphqlサーバ

具体的な方法はここからパクります。

https://github.com/vercel/next.js/blob/canary/examples/with-apollo/lib/apolloClient.js

Next.js公式の実例集ですね。

ここから必要な部分だけ抜き取っていきます。

具体的には👇ここら辺ですね。

```js:vercel/next.js/blob/canary/examples/with-apollo/lib/apolloClient.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
}
```

#### 

注目するポイントはまずここ

```js:vercel/next.js/blob/canary/examples/with-apollo/lib/apolloClient.js
  // 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の概要理解」とか書いておきながらアレですが、下記の記事が勉強になります。

https://speakerdeck.com/aiji42/70mo-tong-rifalseurlwochi-tuwebsabisuwo-next-dot-jsniripureisusitegao-su-hua-sitahua

そうすることで、Next.jsは、多様なアプリケーションに対応するために、HTMLを生成する方法を複数用意しています。

（上記とほぼ同じこと言ってます。）

HTMLはどこで生成して、どうやって受け取るかの話ですが、Apollo Clientで切り分けられています。

特に、まずここ

```js:vercel/next.js/blob/canary/examples/with-apollo/lib/apolloClient.js
  // For SSG and SSR always create a new Apollo Client
  if (typeof window === 'undefined') return _apolloClient
```

　サーバーサイドで実行される、

- 「ビルド時」にデータを取得する`getStaticProps`
- 「ビルド時」にデータを取得する（Dynamic Routing を作る）`getStaticPaths`

のところでは、Apollo Clientを使う場合は、毎回新しいApollo Clientインスタンスが作成されます。

次にここ

```js:vercel/next.js/blob/canary/examples/with-apollo/lib/apolloClient.js
  // Create the Apollo Client once in the client
  if (!apolloClient) apolloClient = _apolloClient
```

クライアントで実行されるクエリの発行などは、最初に1回だけ`apolloClient`を作れば使い回されます。

このサーバーサイドの処理と、クライアントサイドの処理の切り分けが適切にされていないと

アプリケーション実行に、SSGやISRなどの実行が思った通りに行かないことがあると思います。

だから結構大事な処理になるので覚えておきましょう！

では、次回以降で具体的な実装方法を見ていきましょう。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103