Понимание механизма кэширования в Apollo Client
Apollo Client — это мощная библиотека для взаимодействия с GraphQL-сервером, и одним из её ключевых преимуществ является встроенное кэширование. Кэш позволяет значительно ускорить работу приложения, снизить нагрузку на сервер и обеспечить более плавный пользовательский опыт. Прежде чем приступить к настройке, важно понимать, что Apollo Client использует нормализованное хранилище (InMemoryCache), где данные организуются по типу и идентификатору. Это позволяет переиспользовать данные разных запросов и обновлять их по частям.
Кэширование работает автоматически при правильной настройке, но для полного контроля разработчику необходимо понимать, как именно кэш сохраняет и извлекает данные, а также как его можно конфигурировать под конкретные задачи.
---
Настройка InMemoryCache: базовые шаги
Шаг 1: Установка Apollo Client
Если вы ещё не установили Apollo Client, начните с этого шага:
```bash
npm install @apollo/client graphql
```
Импортируйте необходимые модули и создайте клиент:
```js
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://your-graphql-endpoint.com/graphql',
cache: new InMemoryCache(),
});
```
На этом этапе кэш уже активен и будет сохранять результаты запросов при совпадении идентификаторов.
---
Шаг 2: Настройка ключей идентификации
По умолчанию Apollo использует `__typename` и `id` для определения уникальности объекта. Если ваш сервер возвращает другой тип идентификатора, настройте `typePolicies`:
```js
const client = new ApolloClient({
uri: 'https://your-endpoint.com/graphql',
cache: new InMemoryCache({
typePolicies: {
Product: {
keyFields: ['slug'], // если 'id' отсутствует
},
},
}),
});
```
Неправильная настройка `keyFields` может привести к тому, что кэш не будет работать корректно — данные не будут обновляться или могут дублироваться.
---
Управление стратегиями кэширования
Шаг 3: Использование fetchPolicy
Apollo позволяет задавать политику извлечения данных для каждого запроса с помощью параметра `fetchPolicy`. Это определяет, откуда будут браться данные — из кэша или с сервера.
- `cache-first` – сначала ищет в кэше, если нет — обращается к серверу (по умолчанию)
- `network-only` – всегда запрашивает с сервера, игнорируя кэш
- `cache-only` – берёт данные только из кэша
- `no-cache` – выполняет запрос, но не сохраняет результат в кэш
Пример:
```js
useQuery(GET_PRODUCTS, {
fetchPolicy: 'cache-first',
});
```
Совет: для данных, которые редко обновляются (например, категории товаров), используйте `cache-first`. Для чувствительных данных — `network-only`.
---
Шаг 4: Обновление кэша вручную
Иногда автоматического обновления недостаточно, особенно после мутаций. В таких случаях используйте `cache.modify()` или `update()` внутри мутации:
```js
update(cache, { data: { addProduct } }) {
cache.modify({
fields: {
products(existingProducts = []) {
return [...existingProducts, addProduct];
},
},
});
}
```
Это гарантирует, что список продуктов обновится сразу, без повторного запроса. Важно действовать осторожно — ошибочное обновление может повредить структуру кэша.
---
Частые ошибки при кэшировании
Несовпадение идентификаторов
Если сервер не возвращает `__typename` или `id`, Apollo не сможет правильно нормализовать данные. Всегда проверяйте, что каждый объект имеет уникальный идентификатор.
Игнорирование типовой политики
Без правильно настроенных `typePolicies`, кэш может вести себя непредсказуемо. Особенно это важно в списках, где объекты могут повторяться или заменяться.
---
Рекомендации от практиков
- Определяйте кэш как источник правды там, где это возможно. Это уменьшает количество сетевых запросов и повышает отзывчивость интерфейса.
- Используйте фрагменты для обновления частей кэша. Это помогает избежать перезаписи всех данных и делает код более читаемым.
- Проверяйте кэш через Apollo DevTools. Это отличный инструмент для отладки структуры кэша и выявления проблем с идентификацией объектов.
---
Заключение
Кэширование в Apollo Client — это не просто удобное дополнение, а фундаментальная часть архитектуры приложений, использующих GraphQL. Грамотно настроенный кэш позволяет ускорить загрузку данных, уменьшить нагрузку на сервер и обеспечить консистентность между запросами. Изучите поведение `InMemoryCache`, настройте `typePolicies` и научитесь управлять кэшем вручную — эти шаги помогут вам избежать типичных проблем и построить надёжное клиентское приложение.



