问题
I read the docs on interacting with cached data and while I understand how cacheRedirects
works, I'm a bit confused why it is needed in the first place. This is part of the reason why I asked this other question: Does the Apollo client cache nested objects in React?
We know that the data is most likely already in the client cache, but because it's requested with a different query, Apollo Client doesn't know that.
Why is that?
Copy-pasting the example in the docs, for clarity:
query ListView {
books {
id
title
abstract
}
}
query DetailView {
book(id: $id) {
id
title
abstract
}
}
回答1:
Apollo caches the data it receives in a normalized manner.
If your ListView
returns data like:
{
"data": {
"books": [
{
"id": 1,
"title" "ABC",
"__typename": "Book"
},
{
"id": 2,
"title" "DEF",
"__typename": "Book"
}
]
}
}
each book will be stored in the cache under a key based on its id
and __typename
(Book:1
, Book:2
, etc.). This particular list of cache keys is then associated with the books
root field. If you request books
again, Apollo will see it has that query in the cache already and will recreate the result based on the list of keys.
If books
takes some arguments, then each set of arguments is treated as a different cache entry. books(onSale: true)
might return a different set of books than books(subject: "Computer Science")
. Each set of cache keys is stored separately. If you run the first query and then the second, the second will be a cache miss and will still hit the server.
Similarly, you can have a query that takes some arguments and returns a single book, like book(id: 1)
. In all these examples, though, Apollo doesn't "understand" what the arguments id
and onSale
are. How these arguments relate to the returned results is part of your business logic. All Apollo "knows" is that given this query and this set of arguments, you get this particular object or array of objects.
As a human, I can infer from naming that a query like book(id: 2)
returns a single book with the id of 2
. But there's no way for a library like Apollo to accurately infer that information -- how could it guess the correct type for the field or that it returns a single object instead of an array of objects? For that matter, how can it infer that id: 2
translates to "Book where id = 2"? After all, the actual arguments could look any number of ways: book(identifier: 2)
, book(filter: { id: 2 })
, etc.
So we use cacheRedirects
to "teach" Apollo how to look up data that may already be in our cache. This effectively duplicates some of the business logic that normally resides on the server, but helps us avoid an additional call to the server.
来源:https://stackoverflow.com/questions/58844886/why-do-we-need-cacheredirects-at-all