はじめに
apollo client V3.0のベータ版がリリースされ、そろそろcacheを使いこなしたいと思う今日この頃。凡ミスで時間を取られたので、備忘録として残しておきます。
今回出会った問題
今回はコメントリストを呼び出す例を題材に出会った問題を書き残しておきます。
Server側の実装
まずは以下のようなサーバー側のコードを考えます。
const { ApolloServer, gql } = require("apollo-server");
const typeDefs = gql`
type Comment {
id: ID
title: String
comment: String
}
type Query {
commentDetail(title: String): Comment
}
`;
const commentsList = [
{
id: 1,
title: "初めて利用してみた",
comment: "このサービスは素晴らしい"
},
{
id: 1,
title: "何回でも使いたくなるサービス",
comment: "こんな素晴らしいサービスは見たことが無い"
}
];
const resolvers = {
Query: {
commentDetail: (root, args) => {
const com = commentsList.find(p => p.title === args.title);
return com;
}
}
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
commentListのidが重複してるのに気づくと思います。
この状態でcacheを有効化してみたいと思います。
cacheの設定
InMemoryCacheを使います
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client";
const link = new HttpLink({
uri: "http://localhost:4000/graphql"
});
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
fetchPolicy: "cache-first"
}
}
});
上のようにApolloClientを呼び出す際、fetchPolicy
に"cache-first"
を指定してあります。ただデフォルトで"cache-first"
が指定されているので、書いても書かなくても同じです。
query
今回以下の2つのqueryを交互に投げてcacheはどう保存されていくか、確認します
const COMMENTS_QUERY = gql`
{
commentDetail(title:"初めて利用してみた"){
id
comment
}
}
`;
const COMMENTS_QUERY = gql`
{
commentDetail(title:"何回でも使いたくなるサービス"){
id
comment
}
}
`;
結果
InMemorycache
のdata
内部にROOT_QUERY
があり、そこに呼び出されたデータが蓄積されていきます。そしてidが付いているものは、__ref
に参照先が追加され、ROOT_QUERY
と同階層に参照元データが追加されて行きます。今回idを同じに設定したため __ref
が同じcacheを見に行き、表示が更新されないということになっています。(下にcacheの中身の参考画像を貼ります。)
これはidをちゃんとユニークにつけておけば問題ないです。
idをつけなかったらどうなるか
今idが同じものであったためにcacheの重複が起こりました。idを消すと__ref
が消え、ROOT_QUERYにデータが全て保存されるようになります。今回の場合、commentDetail({"title":"何回でも使いたくなるサービス"})
の部分がkeyになり、cacheにどんどん保存されます。この場合だと参照先がないので、同じデータを見にいくことはありません。しかしこの場合もtitle
が同じ場合は希望通りの挙動が出ない場合があるので、idはちゃんと降っておいたほうがいいかなと思います。
参考文献
以下の記事を参考にさせていただきました。ありがとうございました。
apollo-clientを使っていてデータが変に重複してる(キャッシュが変)?と思った時に見てみる事