I'm new to GraphQL and I thought it would do this automatically.
Eg if I fetch a list of posts, then open an individual post, the data for that post is already in memory. I expected GraphQL to be able to re-use the data from cache, but it makes another network request.
The schema is something like:
type Query {
posts: [Post]
post(id: ID): Post
}
I'm using React. In PostsRoute
, I have:
useQuery(gql`
query {
posts {
id
title
}
}
`);
In PostRoute
, I have:
useQuery(gql`
query {
post(id: ${postId}) {
id
title
}
}
`);
Is there something I need to configure for Apollo to use the cached data automatically? Or is this something that Apollo doesn't support by default?
Apollo 2
If you are using Apollo 2, what you're looking for is probably cacheRedirects . It is used to intercept a query and resolve it using the cache. The linked document actually explains exactly your use-case so I recommend you look at it, but for posterity, here's how I do it personally (adapted to your situation).
In your InMemoryCache
options when you instantiate it, add a cacheRedirects
field and specify a custom resolver for your post
query, like so:
const cache = new InMemoryCache({
cacheRedirects: {
Query: {
post: (_, {id}, {getCacheKey}) => getCacheKey({__typename: "Post", id}),
},
},
});
This assumes that the __typename
of your post is Post
. First argument of the custom resolver is the result of the ROOT_QUERY
, which we don't use here. Second argument is the arguments that are passed to the query ( {id: "some_id"}
here) and the third one is the context, containing client
, cache
and getCacheKey
. Only getCacheKey
is useful to us here. That method take a __typename
and an id
, and returns its key in the cache.
This completes the custom resolver. Now when you query post(id: some_id)
it will look at the custom resolver, receive the cache key and return the result from the cache matching that key.
Apollo 3
cacheRedirects
has been removed in Apollo 3, but the same functionality can be achieved with field policies . You still need to set it up when instantiating InMemoryCache
, but it's slightly different:
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
post: (_, {args, toReference}) => toReference({__typename: "Post", id: args.id}),
},
},
},
});
We define a field policy read on the field post
on type Query
. Note that the second argument now includes both args
and the helper utilities. This includes toReference
, that's basically the new getCacheKey
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.