Кэшировать запрос GraphQL с несколькими идентификаторами с помощью Apollo

мы используем клиент apollo в веб-приложении и ищем способы улучшить использование кеша.

У нас есть запрос, который принимает в качестве параметра массив идентификаторов, пример запроса с идентификаторами foo и bar будет выглядеть так:

query routes {
  routes(routeNames: ["foo", "bar"]) {
    items {
      name
      route
      defaults
    }
  }
}

Настройка кеша выглядит так:

export const cacheRedirects = {
  Query: {
    routes: (_: any, args: RoutesArgs, { getCacheKey }: Resolver<'name'>): Array<CacheKey> =>
      args.routeNames.map(name => getCacheKey({ __typename: 'Route', name })),
  },
};

export const dataIdFromObject = (object: QueryResult): ?string => {
  switch (object.__typename) {
    case 'Route':
      return `${object.__typename}:${object.name}`;
    default: return defaultDataIdFromObject(object);
  }
};

export function newCache(): InMemoryCache {
  return new InMemoryCache({ dataIdFromObject, cacheRedirects });
}

Теперь при использовании запроса в нескольких местах нашего клиента мы хотели бы получать только данные для routeNames, не кэшированных через сеть, а остальные получать через кеш.

Итак, проблема сводится к следующему: При наличии одного запроса, который кэширует результаты для routeNames: ["foo", "bar"], а позже появляется другой запрос, запрашивающий маршруты для routeNames: ["bar", "baz"], мы хотели бы взять результат, соответствующий "bar", из кеша и отправить запрос для routeNames: ["baz"].

Я не уверен, можно ли и как это сделать с Apollo, потому что в отличие от cacheRedirect пример здесь мы имеем дело с несколькими идентификаторами, а не с одним.


Теперь, если мы не можем кэшировать для каждого элемента массива, следующее лучшее, что мы могли бы сделать, - это преобразовать идентификаторы в общие ключи кеша, чтобы ["foo", "bar"] и ["bar", "foo"] в конечном итоге использовали один и тот же ключ кеша, но ["foo", "baz"] использовал бы другой.

Конечно, идеальным вариантом было бы получить только "baz" как недостающий элемент в нашем сценарии.

Отличный вопрос! Что у тебя в итоге получилось?

Josh Unger 03.02.2021 17:16

Спасибо :) - ~ 3 года назад я сделал проект apollo-link для переписывания запросов, но где-то в августе 2018 потерял на нем внимание. Итак, что-то было начато, но так и не закончено, и я считаю, что с тех пор Apollo существенно реструктурировал свою кодовую базу - так что я не ожидайте, что какой-либо из моих предыдущих кодов будет в полезном состоянии. Я думаю, что для практических целей это стало комбинацией двух вещей: некоторые части схемы теперь легче кэшировать / использовать, а о других мы в настоящее время не заботимся.

Jakob Runge 06.02.2021 11:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
2
1 488
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Чтобы проверить кеш, не касаясь сети, используйте readQuery() или readFragment().

Документация здесь:

https://www.apollographql.com/docs/react/advanced/caching.html#readqueryhttps://www.apollographql.com/docs/react/advanced/caching.html#readfragment

ОБНОВЛЕНИЕ: в качестве альтернативы вы также можете установить fetchPolicy на cache-only в параметрах запроса.

https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-options-fetchPolicy

ОБНОВЛЕНИЕ 2: Хороший способ интегрировать проверки, чтобы они запускались для каждого запроса, может быть настраиваемым промежуточным программным обеспечением клиента, которое будет запускаться при каждом запросе перед вызовом сервера.

https://www.apollographql.com/docs/react/advanced/network-layer.html#linkMiddleware

Привет, спасибо - мы исследуем подход промежуточного программного обеспечения. Я приму соответственно;)

Jakob Runge 03.08.2018 11:23

Другие вопросы по теме