Когда использовать Apachelo cacheRedirects? - PullRequest
0 голосов
/ 22 октября 2018

В документации Apollo обсуждается использование cacheRedirects для указания Apollo, как получить доступ к данным, уже находящимся в кеше, из другого запроса.

В качестве примера приводится:

В некоторых случаях запрос запрашивает данные, которые уже существуют в клиентском хранилище, под другим ключом.Очень распространенным примером этого является случай, когда ваш пользовательский интерфейс имеет представление списка и подробное представление, которые используют одни и те же данные.В представлении списка может выполняться следующий запрос:

query ListView {books {id title abstract}}

Когда выбрана конкретная книга, в подробном представлении отображается отдельный элемент с помощью этого запроса:

query DetailView {book (id: $ id) {id title abstract}}

Мы знаем, что данные, скорее всего, уже находятся в кэше клиента, но поскольку они запрашиваются другим запросом,Клиент Apollo этого не знает.Чтобы сообщить клиенту Apollo, где искать данные, мы можем определить собственные распознаватели

Я пытаюсь понять , почему это необходимо для этого примера.Если запрос books возвращает массив типа Book, а запрос book возвращает один объект типа Book, то, несомненно, нормализованный кеш уже будет иметь данные для каждой из книг (из запроса ListView) на основе typename и id, и запрос DetailView может использовать эту информацию напрямую без какого-либо дополнительного вмешательства.Вместо этого нам предлагают написать некоторый код, чтобы помочь ему:

const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      book: (_, args, { getCacheKey }) =>
        getCacheKey({ __typename: 'Book', id: args.id })
    },
  },
});

При каких обстоятельствах ApolloClient не в состоянии выяснить это самостоятельно и почему?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Просто запоздалая мысль: это связано с дизайном GraphQL.В GraphQL book(id) его распознаватель может свободно интерпретировать id так, как им нравится.Это просто вызов функции с одним параметром, который возвращает экземпляр типа Book.

GraphQL фактически ничего не говорит об идентификаторах.Он только распознает __typename как особый.

Only Relay и, в некоторой степени, Apollo, добавляют понятие идентификаторов объектов позже.Тем не менее, они используют несколько иной подход, поскольку Relay переводит вашу схему GraphQL в более жесткую, формальную структуру.

Существует даже дополнительное осложнение (упомянутое и в другом ответе) о том, что схема недоступна для клиента (поэтому клиент даже не знает, book вернет Book без выполнения запроса).Это снова следует из спецификации GraphQL.

0 голосов
/ 22 октября 2018

Кажется очевидным и интуитивно понятным, что с учетом запроса, подобного приведенному ниже, мы извлекаем один объект Book по его свойству id.

query DetailView($id: ID) {
  book(id: $id) {
    id
    title
    abstract
  }
}

Однако в этом примере имяаргумента здесь (id) просто совпадает с именем свойства, используемого кешем (id).Вне соглашения нет ничего, что говорит, что сам аргумент нельзя назвать bookId, bookID или supercalifragilisticexpialidocious.Даже если запрос возвращает тип Book и принимает один или несколько аргументов, Apollo не может определить, какой аргумент фактически является идентификатором, который использовался при нормализации кэша.Точно так же, если существуют другие аргументы, они могут иметь или не иметь значения в отношении того, может ли использоваться то, что в данный момент кэшировано, или нет - для определения этого необходима дополнительная логика.

Другое соображение здесь заключается в том, что за пределами необязательнопередавая экземпляр IntrospectionFragmentMatcher вашему InMemoryCache, Apollo фактически не знает, что представляет собой схема конечной точки, которую он запрашивает.Типы, используемые кешем при нормализации, определяются после запроса, полученного с использованием свойства __typename.Весь смысл cacheRedirects состоит в том, чтобы предотвратить запуск запроса, если элемент или элементы уже находятся в кэше.Однако, учитывая конкретный запрос, Apollo не может знать, что он будет возвращать определенный тип до тех пор, пока не вернется этот запрос.cacheRedirects предоставляет способ сказать "этот запрос будет возвращать этот конкретный тип", даже не запустив запрос в первую очередь.

...