Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edits to reading and writing cached data #7864

Merged
merged 5 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/source/api/cache/InMemoryCache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ readQuery<QueryType, TVariables = any>(

Writes data to the cache in the shape of a provided GraphQL query. Returns a `Reference` to the written object or `undefined` if the write failed.

For usage instructions, see [Interacting with cached data: `writeQuery`](../../caching/cache-interaction/#writequery-and-writefragment).
For usage instructions, see [Interacting with cached data: `writeQuery`](../../caching/cache-interaction/#writequery).

Takes an `options` object as a parameter. Supported fields of this object are described below.

Expand Down Expand Up @@ -398,7 +398,7 @@ readFragment<FragmentType, TVariables = any>(

Writes data to the cache in the shape of the provided GraphQL fragment. Returns a `Reference` to the written object or `undefined` if the write failed.

For usage instructions, see [Interacting with cached data: `writeFragment`](../../caching/cache-interaction/#writequery-and-writefragment).
For usage instructions, see [Interacting with cached data: `writeFragment`](../../caching/cache-interaction/#writefragment).

Takes an `options` object as a parameter. Supported fields of this object are described below.

Expand Down Expand Up @@ -567,7 +567,7 @@ Modifies one or more field values of a cached object. Must provide a **modifier

Returns `true` if the cache was modified successfully and `false` otherwise.

For usage instructions, see [`cache.modify`](../../caching/cache-interaction/#cachemodify).
For usage instructions, see [Using `cache.modify`](../../caching/cache-interaction/#using-cachemodify).

Takes an `options` object as a parameter. Supported fields of this object are described below.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/api/react/hoc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ This option allows you to update your store based on your mutation’s result. B

`options.update` takes two arguments. The first is an instance of a `DataProxy` object which has some methods which will allow you to interact with the data in your store. The second is the response from your mutation - either the optimistic response, or the actual response returned by your server (see the mutation result described in the [mutation render prop](./components/#render-prop-function-1) section for more details).

In order to change the data in your store call methods on your `DataProxy` instance like [`writeQuery` and `writeFragment`](../../caching/cache-interaction/#writequery-and-writefragment). This will update your cache and reactively re-render any of your GraphQL components which are querying affected data.
In order to change the data in your store call methods on your `DataProxy` instance like [`writeQuery`](../../caching/cache-interaction/#writequery) and [`writeFragment`](../../caching/cache-interaction/#writefragment). This will update your cache and reactively re-render any of your GraphQL components which are querying affected data.

To read the data from the store that you are changing, make sure to use methods on your `DataProxy` like [`readQuery`](../../caching/cache-interaction/#readquery) and [`readFragment`](../../caching/cache-interaction/#readfragment).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: Configuring the cache
sidebar_title: Configuration
---

import {ExpansionPanel} from 'gatsby-theme-apollo-docs';

Apollo Client stores the results of its GraphQL queries in a normalized, in-memory cache. This enables your client to respond to future queries for the same data without sending unnecessary network requests.

This article describes cache setup and configuration. To learn how to interact with cached data, see [Reading and writing data to the cache](./cache-interaction).
Expand Down Expand Up @@ -54,12 +56,14 @@ To customize cache behavior, provide an `options` object to the `InMemoryCache`
###### `addTypename`

`Boolean`

</td>
<td>

If `true`, the cache automatically adds `__typename` fields to all outgoing queries, removing the need to add them manually.

The default value is `true`.

</td>
</tr>

Expand All @@ -69,12 +73,14 @@ The default value is `true`.
###### `resultCaching`

`Boolean`

</td>
<td>

If `true`, the cache returns an identical (`===`) response object for every execution of the same query, as long as the underlying data remains unchanged. This makes it easier to detect changes to a query's result.

The default value is `true`.

</td>
</tr>

Expand All @@ -84,6 +90,7 @@ The default value is `true`.
###### `possibleTypes`

`Object`

</td>
<td>

Expand All @@ -92,6 +99,7 @@ Include this object to define polymorphic relationships between your schema's ty
Each key in the object is the `__typename` of an interface or union, and the corresponding value is an array of the `__typename`s of the types that belong to that union or implement that interface.

For an example, see [Defining `possibleTypes` manually](../data/fragments/#defining-possibletypes-manually).

</td>
</tr>

Expand All @@ -101,12 +109,14 @@ For an example, see [Defining `possibleTypes` manually](../data/fragments/#defin
###### `typePolicies`

`Object`

</td>
<td>

Include this object to customize the cache's behavior on a type-by-type basis.

Each key in the object is the `__typename` of a type to customize, and the corresponding value is a [`TypePolicy` object](#typepolicy-fields).

</td>
</tr>

Expand All @@ -116,12 +126,14 @@ Each key in the object is the `__typename` of a type to customize, and the corre
###### `dataIdFromObject`

`Function`

</td>
<td>

**Deprecated.** A function that takes a response object and returns a unique identifier to be used when normalizing the data in the store.

Deprecated in favor of the `keyFields` option of the [`TypePolicy` object](#typepolicy-fields).

</td>
</tr>
</tbody>
Expand Down Expand Up @@ -234,6 +246,83 @@ To disable normalization for a type, define a `TypePolicy` for the type (as show

Objects that are not normalized are instead embedded within their _parent_ object in the cache. You can't access these objects directly, but you can access them via their parent.

## Visualizing the cache

To help understand the structure of your cached data, we strongly recommend installing the [Apollo Client Devtools](../development-testing/developer-tooling/#apollo-client-devtools).

This browser extension includes an inspector that enables you to view all of the normalized objects contained in your cache:

<img src="../img/cache-inspector.jpg" class="screenshot" alt="The Cache tab of the Apollo Client Devtools"></img>

### Example

Let's say we use Apollo Client to run the following query on the [SWAPI demo API](https://github.com/graphql/swapi-graphql):

```graphql
query {
allPeople(first:3) { # Return the first 3 items
people {
id
name
homeworld {
id
name
}
}
}
}
```

This query returns the following result of three `Person` objects, each with a corresponding `homeworld` (a `Planet` object):

<ExpansionPanel title="Click to expand">

```json
{
"data": {
"allPeople": {
"people": [
{
"id": "cGVvcGxlOjE=",
"name": "Luke Skywalker",
Copy link
Member

@benjamn benjamn Mar 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add the __typename: "Person" (and "Planet") fields to this data, and add a note about Apollo Client automatically adding those fields to the query? Otherwise it may be hard to understand how the normalization makes use of the __typename information.

"homeworld": {
"id": "cGxhbmV0czox",
"name": "Tatooine"
}
},
{
"id": "cGVvcGxlOjI=",
"name": "C-3PO",
"homeworld": {
"id": "cGxhbmV0czox",
"name": "Tatooine"
}
},
{
"id": "cGVvcGxlOjM=",
"name": "R2-D2",
"homeworld": {
"id": "cGxhbmV0czo4",
"name": "Naboo"
}
}
]
}
}
}
```

</ExpansionPanel>

After the result is cached, we can view the state of our cache in the Apollo Client Devtools:

<img src="../img/cache-inspector.jpg" class="screenshot" alt="The Cache tab of the Apollo Client Devtools"></img>

Our cache now contains five normalized objects (in addition to the `ROOT_QUERY` object): three `Person` objects and two `Planet` objects.

**Why do we only have two `Planet` objects?** Because two of the three returned `Person` objects have the same `homeworld`. By [normalizing data](#data-normalization) like this, Apollo Client can cache a single copy of an object, and multiple _other_ objects can include _references_ to it (see the `__ref` field of the object in the screenshot above).


## `TypePolicy` fields

To customize how the cache interacts with specific types in your schema, you can provide an object mapping `__typename` strings to `TypePolicy` objects when you create a new `InMemoryCache` object.
Expand Down
Loading