はじめに
HasuraのGraphQlサーバからデータフェッチした後、Apolloが作成したキャッシュのデータを今度は取得する実装をします。
それを通じて、Apollo のキャッシュ機構を理解していきましょう。
最終的なゴール
以下のような構成のアプリを作ることです。
目的
- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上
前回のおさらい
Next.jsとHasuraを連携してデータを画面に出すため
- apolloClientクライアントを作成し
- apolloの
useQuery
というcustomHookをつかってデータフェッチ
を経て、Hasuraで作成したデータを表示させるところまでやりました。
詳細👇
Hasuraからデータ取得した結果をApolloでキャッシュさせて、そのデータを取得するまでを解説
この記事の全体感
2つのファイル(ページ)を行き来して、ChromeのNetworkタブ見て、データフェッチの違いを見ていきます。
2つのファイルは同じデータを表示しているのに取得方法が違います。
- hasura-main.tsx は HasuraのGraphQlサーバからデータフェッチしてる
- hasura-sub.tsx は Apolloが作成したキャッシュしたデータを取得している
ファイルの用意
キャッシュからデータを取得する方のファイルを用意します。
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
と異なる注目ポイントは矢印の部分だけです。
GET_USERS
からGET_USERS_LOCAL
に、変わるだけで
もう少し細かくいうと、queries/queries.ts
を見ましょう。クエリの実態があるファイルですね。
以前、説明しましたが。
@client
があるかないか、この違いだけで、サーバーサイドを読みに行かずに、存在するクライアントにあるキャッシュを取得しにいきます。
前の記事で作成した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
検証
コードが書けたので、検証してみましょう。
検証することは
- hasura-main.tsx は HasuraのGraphQlサーバからデータフェッチしてる
- hasura-sub.tsx は Apolloが作成したキャッシュしたデータを取得している
ですね。
main page にアクセスすると
Graph Qlサーバから最新の情報をフェッチしていることがわかります。
それでは、作成したリンクから、hasura-sub.tsx
に行きます。
すると、Network
タブを見ても、Graph Qlサーバから最新の情報をフェッチしていませんね。
図で表すとこんな感じ👇
Graph Qlサーバから最新の情報をフェッチしている場合こうなります。
graphqlが増えましたね。これは、hasura-sub.tsx
でも、Graph Qlサーバから最新の情報をフェッチしていることを表しています。
その場合のコードはこういう感じです。👇(パカっと開いてね)
hasura-sub.tsxでもGraph Qlサーバからフェッチする書き方
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
は、クライアントにデータがあれば、そこから取得してしまうので
そうならないように、必ずサーバからデータを取得するように指定しています。
今日のところは以上です。
次の記事では、今日1つ紹介した apolloのfetchPolicy
以外のやつを紹介します。
アウトプット100本ノック実施中