Hasuraからデータ取得した結果をApolloでキャッシュさせて、そのデータを取得させるまでを解説

## はじめに

HasuraのGraphQlサーバからデータフェッチした後、Apolloが作成したキャッシュのデータを今度は取得する実装をします。

![スクリーンショット 2021-11-03 21.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/7da9815a-ff5c-8dd5-0e82-b78b6cfe7ed2.png)

それを通じて、Apollo のキャッシュ機構を理解していきましょう。

## 最終的なゴール

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

![スクリーンショット 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)

### 目的

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

## 前回のおさらい

Next.jsとHasuraを連携してデータを画面に出すため

- apolloClientクライアントを作成し
- apolloの`useQuery`というcustomHookをつかってデータフェッチ

を経て、Hasuraで作成したデータを表示させるところまでやりました。

詳細👇

https://qiita.com/ryosuketter/items/c7bc79b02a597043ba2d

## Hasuraからデータ取得した結果をApolloでキャッシュさせて、そのデータを取得するまでを解説

### この記事の全体感

![_落書き__資料作成用_-_Google_スライド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/cd5837cf-7c88-b4df-9533-5fac21c7566a.png)

2つのファイル（ページ）を行き来して、ChromeのNetworkタブ見て、データフェッチの違いを見ていきます。

2つのファイルは同じデータを表示しているのに取得方法が違います。

- hasura-main.tsx は HasuraのGraphQlサーバからデータフェッチしてる
- hasura-sub.tsx は Apolloが作成したキャッシュしたデータを取得している

### ファイルの用意

キャッシュからデータを取得する方のファイルを用意します。

```
pages/hasura-sub.tsx
```

### コード

```tsx:pages/hasura-sub.tsx
import { VFC } from 'react'
import Link from 'next/link'
import { useQuery } from '@apollo/client'
import { GET_USERS_LOCAL } from '../queries/queries'
import { GetUsersQuery } from '../types/generated/graphql'
import { Layout } from '../components/Layout'

const FetchSub: VFC = () => {
  const { data } = useQuery<GetUsersQuery>(GET_USERS_LOCAL)
  return (
    <Layout title="Hasura fetchPolicy read cache">
      <p className="mb-6 font-bold">Direct read out from cache</p>
      {data?.users.map((user) => {
        return (
          <p className="my-1" key={user.id}>
            {user.name}
          </p>
        )
      })}
      <Link href="/hasura-main">
        <a className="mt-6">Back</a>
      </Link>
    </Layout>
  )
}
export default FetchSub
```

文言以外で、`hasura-main`と異なる注目ポイントは矢印の部分だけです。

![hasura-sub_tsx_—_nextjs-hasura-basic-lesson.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/4cf368dc-36e0-361e-4f89-bfb667542392.png)

`GET_USERS`から`GET_USERS_LOCAL`に、変わるだけで

もう少し細かくいうと、`queries/queries.ts`を見ましょう。クエリの実態があるファイルですね。

以前、説明しましたが。

![queries_ts_—_nextjs-hasura-basic-lesson.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/32f490b6-fd59-23b2-bd83-1a1a4338abbd.png)

`@client`があるかないか、この違いだけで、サーバーサイドを読みに行かずに、存在するクライアントにあるキャッシュを取得しにいきます。

<details>
<summary>前の記事で作成したhasura-main.tsx</summary><div>


```tsx:pages/hasura-main.tsx

import { VFC } from 'react'
import Link from 'next/link'
import { useQuery } from '@apollo/client'
import { GET_USERS } from '../queries/queries'
import { GetUsersQuery } from '../types/generated/graphql'
import { Layout } from '../components/Layout'

const FetchMain: VFC = () => {
  const { data, error } = useQuery<GetUsersQuery>(GET_USERS)
  if (error)
    return (
      <Layout title="Hasura fetchPolicy">
        <p>Error: {error.message}</p>
      </Layout>
    )
  return (
    <Layout title="Hasura fetchPolicy">
      <p className="mb-6 font-bold">Hasura main page</p>
      {data?.users.map((user) => {
        return (
          <p className="my-1" key={user.id}>
            {user.name}
          </p>
        )
      })}
      <Link href="/hasura-sub">
        <a className="mt-6">Next</a>
      </Link>
    </Layout>
  )
}
export default FetchMain

```

</div></details>

### 検証 

コードが書けたので、検証してみましょう。

検証することは

```
- hasura-main.tsx は HasuraのGraphQlサーバからデータフェッチしてる
- hasura-sub.tsx は Apolloが作成したキャッシュしたデータを取得している
```

ですね。

main page にアクセスすると

Graph Qlサーバから最新の情報をフェッチしていることがわかります。

![Hasura_fetchPolicy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/f8447bb1-535b-e3be-215b-4d700cd990ec.png)

それでは、作成したリンクから、`hasura-sub.tsx`に行きます。

![9b44920ff451ada678de3e2d01dd59d3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/cd6e9d11-1951-1132-46af-a4393f3cbbde.gif)

すると、`Network`タブを見ても、Graph Qlサーバから最新の情報をフェッチしていませんね。

図で表すとこんな感じ👇

![スクリーンショット 2021-11-04 1.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/ed2efa4e-e62d-10a1-42c2-696c492be6a9.png)

Graph Qlサーバから最新の情報をフェッチしている場合こうなります。

![f9d64fb5c2626c29268aa21ad481ee37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/06aad872-0a72-1211-38d7-4499f1ef96f0.gif)

graphqlが増えましたね。これは、`hasura-sub.tsx`でも、Graph Qlサーバから最新の情報をフェッチしていることを表しています。

![スクリーンショット 2021-11-04 1.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/bca1e3cd-9130-d346-49b2-f54d328a1407.png)

その場合のコードはこういう感じです。👇（パカっと開いてね）

<details>
<summary>hasura-sub.tsxでもGraph Qlサーバからフェッチする書き方</summary><div>


```tsx:pages/hasura-sub.tsx

import { VFC } from 'react'
import Link from 'next/link'
import { useQuery } from '@apollo/client'
import { GET_USERS } from '../queries/queries'
import { GetUsersQuery } from '../types/generated/graphql'
import { Layout } from '../components/Layout'

const FetchSub: VFC = () => {
  const { data } = useQuery<GetUsersQuery>(GET_USERS, {
    fetchPolicy: 'network-only',
  })
  return (
    <Layout title="Hasura fetchPolicy read cache">
      <p className="mb-6 font-bold">Direct read out from cache</p>
      {data?.users.map((user) => {
        return (
          <p className="my-1" key={user.id}>
            {user.name}
          </p>
        )
      })}
      <Link href="/hasura-main">
        <a className="mt-6">Back</a>
      </Link>
    </Layout>
  )
}
export default FetchSub

```

`fetchPolicy: 'network-only'`を記載しないと、クエリ`GET_USERS`は、クライアントにデータがあれば、そこから取得してしまうので

そうならないように、必ずサーバからデータを取得するように指定しています。

</div></details>

今日のところは以上です。

次の記事では、今日1つ紹介した apolloの`fetchPolicy`以外のやつを紹介します。

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

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