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





Одна из идей состоит в том, чтобы проверить локальный кеш перед выполнением фактического запроса и просто удалить идентификаторы (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
Привет, спасибо - мы исследуем подход промежуточного программного обеспечения. Я приму соответственно;)
Отличный вопрос! Что у тебя в итоге получилось?