Apollo Cache Update
1. Docs
Overview https://www.apollographql.com/docs/react/caching/overview/
Update function
When a mutation's response is insufficient to update all modified fields in your cache (such as certain list fields), you can define an update function to apply manual changes to your cached data after a mutation.
https://www.apollographql.com/docs/react/data/mutations/#the-update-function
Cache interactions
Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache. This enables Apollo Client to respond almost immediately to queries for already-cached data, without even sending a network request.
https://www.apollographql.com/docs/react/caching/cache-interaction/
2. Practice
Cache update after mutation allows to reflect changes in ui without additional network request
There are 5 ways of modifying cache:
- Using GraphQL queries - readQuery / writeQuery
Use standard GraphQL queries for managing both remote and local data. Most suitable for deep nested queries @src\api\index.ts
- Using GraphQL fragments - readFragment / writeFragment
Access the fields of any cached object without composing an entire query to reach that object. Most suitable for flat queries @src\components\workspaces\add-workspace.modal.tsx
- Directly modifying cached fields cache.modify
Manipulate cached data without using GraphQL at all. Requires exact identifier
Each method should be picked according to accessible data and data flow. Components relying on nested quires will be updated according query settings
Underlying data
Normalized data should be preferred as it allows direct field update Non-normalized data should be updated using GraphQL queries (cache or refetch)
Debug
Debug is easier with hooks, as we can see console log, instead of direct use of client. Use maximum typing in cache operations as it allows to see real structure and debug. @src\editor\right-side-panel\property-controls-components\workspace-assets.modal.tsx Typing used in both mutation and query
Data layer architecture
Cache is normalized data storage. And normalized data on backend is highly beneficial. When only children elements know parent it. It allows to write flat queries byParentId, and put them in nested resolvers. This way we can achieve single data graph with modular usage. In this case single-entity cache update is easy and preferable.
- Strapi provides default resolvers. They are not nested. But they resolve by relational DB fields. It allows deep queries out-of-the-box. But in this case readQuery/writeQuery is preferred