How to Use Apollo Cache for Efficient GraphQL Data Management
Use
Apollo Client's cache to store GraphQL query results locally by configuring the InMemoryCache when creating the client. You can read, write, and update cached data using methods like cache.readQuery and cache.writeQuery to improve app responsiveness without extra network requests.Syntax
The Apollo cache is set up by passing an InMemoryCache instance to the Apollo Client. You can then use cache methods to read or write data.
new ApolloClient({ cache: new InMemoryCache() }): Creates a client with cache.cache.readQuery({ query }): Reads cached data for a query.cache.writeQuery({ query, data }): Writes or updates cached data.
javascript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; const client = new ApolloClient({ uri: 'https://example.com/graphql', cache: new InMemoryCache(), }); // Reading from cache const cachedData = client.cache.readQuery({ query: gql`query GetBooks { books { id title } }` }); // Writing to cache client.cache.writeQuery({ query: gql`query GetBooks { books { id title } }`, data: { books: [{ id: '1', title: 'New Book' }] }, });
Example
This example shows how to create an Apollo Client with cache, fetch data, and update the cache manually to reflect changes instantly in the UI.
javascript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; const client = new ApolloClient({ uri: 'https://example.com/graphql', cache: new InMemoryCache(), }); const GET_TODOS = gql` query GetTodos { todos { id text completed } } `; // Initial cache read (empty before query) console.log('Before query:', client.cache.readQuery({ query: GET_TODOS })); // Simulate fetching data and writing to cache const todosData = { todos: [ { id: '1', text: 'Learn Apollo Cache', completed: false }, { id: '2', text: 'Build app', completed: false }, ], }; client.cache.writeQuery({ query: GET_TODOS, data: todosData, }); // Read cache after writing console.log('After write:', client.cache.readQuery({ query: GET_TODOS })); // Update a todo item in cache const updatedTodos = { todos: [ { id: '1', text: 'Learn Apollo Cache', completed: true }, { id: '2', text: 'Build app', completed: false }, ], }; client.cache.writeQuery({ query: GET_TODOS, data: updatedTodos, }); // Read cache after update console.log('After update:', client.cache.readQuery({ query: GET_TODOS }));
Output
Before query: null
After write: { todos: [ { id: '1', text: 'Learn Apollo Cache', completed: false }, { id: '2', text: 'Build app', completed: false } ] }
After update: { todos: [ { id: '1', text: 'Learn Apollo Cache', completed: true }, { id: '2', text: 'Build app', completed: false } ] }
Common Pitfalls
Common mistakes when using Apollo Cache include:
- Trying to read from cache before any data is written, which returns
null. - Not matching the query shape exactly when writing or reading cache data.
- Forgetting to update the cache after mutations, causing UI to show stale data.
- Mutating cached objects directly instead of using
writeQueryorwriteFragment.
Always ensure your queries and cache updates match the GraphQL schema structure.
javascript
/* Wrong: reading cache before data is written returns null */ const dataBefore = client.cache.readQuery({ query: GET_TODOS }); console.log(dataBefore); // null /* Right: write data first, then read */ client.cache.writeQuery({ query: GET_TODOS, data: todosData }); const dataAfter = client.cache.readQuery({ query: GET_TODOS }); console.log(dataAfter); // returns data
Output
null
{ todos: [ { id: '1', text: 'Learn Apollo Cache', completed: false }, { id: '2', text: 'Build app', completed: false } ] }
Quick Reference
| Method | Purpose | Usage Example |
|---|---|---|
| new InMemoryCache() | Creates the cache instance | const cache = new InMemoryCache(); |
| cache.readQuery({ query }) | Reads cached data for a query | cache.readQuery({ query: GET_TODOS }) |
| cache.writeQuery({ query, data }) | Writes or updates cached data | cache.writeQuery({ query: GET_TODOS, data }) |
| cache.modify({ id, fields }) | Updates specific fields in cache | cache.modify({ id: 'Todo:1', fields: { completed: () => true } }) |
| cache.evict({ id }) | Removes an item from cache | cache.evict({ id: 'Todo:1' }) |
Key Takeaways
Initialize Apollo Client with InMemoryCache to enable caching.
Use cache.readQuery and cache.writeQuery to read and update cached data.
Always match the query structure exactly when interacting with the cache.
Update the cache after mutations to keep UI data fresh.
Avoid direct mutation of cached objects; use Apollo cache methods instead.