Apollo Client cache is your single source of truth that holds all of your local data alongside your remote data. But in case of parameterized queries apollo-cache-inmemory it usually very difficult to retrieve client-side data due to stringify key approach in the cache. So apollo-fragment-list-link is the link to read all your client-side fragments with the help of apollo-link-state's @client
directive. It can be used as afterware of apollo-http-link, It will find all updated fragments and will put them in the cache with customizable cache key. apollo has introduced @connection
directive, with help of it, you can control the key of caching, but in case of a different query containing different filtering parameters, it will be very difficult to read all local fragments which we have already fetched. Suppose we have implemented suggestions query, and have already fetched suggestions with some prefix token, Now we want to read all suggestions offline from the cache,
Suppose we have implemented suggestions query, and have already fetched suggestions with some prefix token, Now we want to read all suggestions offline from the cache,
query fetchSuggestion($token: String!) {
suggestions(condition:{$startWith:$token}) {
...SuggestionItem
}
}
fragment SuggestionItem on Suggestion {
id
name
label
}
First query variables:
{"token": "Exa"}
Second query variables:
{"token": "To"}
After queries listed above, partial cache status will be
(without apollo-fragment-list-link)
{
$ROOT_QUERY.fetchSuggestion.(token:"Exa"): [...],
$ROOT_QUERY.fetchSuggestion.(token:"To"): [...],
Suggestion:1,
Suggestion:2,
....
}
(with apollo-fragment-list-link)
{
$ROOT_QUERY.allSuggestions: {
totalCount
nodes: [
{id: "Suggestion:1"},
{id: "Suggestion:2"},
...
]
},
$ROOT_QUERY.fetchSuggestion.(token:"Exa"): [...],
$ROOT_QUERY.fetchSuggestion.(token:"To"): [...],
Suggestion:1,
Suggestion:2,
....
}
const query = gql`
query clientSuggestions {
allSuggestions @client {
nodes {
id
}
}
}
}
`;
const {result} = await client.query({
query,
})
/*
result = [{id:1,__typename:"Suggestion"}, {id:2,__typename:"Suggestion"}, ...]
*/
To get started, install apollo-fragment-list-link
from npm:
npm install apollo-fragment-list-link --save
import { withClientState } from 'apollo-link-state';
import ApolloFragmentLink from 'apollo-fragment-list-link';
// This is the same cache you pass into new ApolloClient
const cache = new InMemoryCache(...);
const fragmentLink = new ApolloFragmentLink({
cache,
fragmentTypeDefs: [
gql`
fragment SuggestionItem on Suggestion {
id
name
}
`,
],
// @optional
createCacheReadKey: ({typename}) => `all${typename}`,
// @optional
createConnectionTypename: ({typename}) => `All${typename}Connection`,
});
const stateLink = withClientState({
cache,
resolvers: {
Query: {
...fragmentLink.createStateLinkQueryResolvers()
},
}
});
const link = stateLink.concat(fragmentLink.concat(httpLink));
export const client = new ApolloClient({
link,
cache,
});
const GET_SUGGESTIONS = gql`
query clientSuggestions {
allSuggestions @client {
nodes {
id
}
}
}
}
`;
const {result} = await client.query({
query: GET_SUGGESTIONS,
})
Finally, each time you make a change in apollo-link-state, you need to run:
yarn bundle
Now you should be good to go!