Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому кешувати GraphQL складніше, ніж REST, і які є рішення?

Чому REST кешується легко: кожен ресурс має свою адресу, читання - через GET, і вся інфраструктура HTTP (браузер, CDN, проксі) розуміє Cache-Control і ETag без жодної участі застосунку.

Чому з GraphQL складніше:

  • одна адреса /graphql для всього;
  • запити через POST - HTTP-кеші їх не кешують;
  • кожен клієнт формує свій запит - навіть однакові дані запитуються різними наборами полів, і ключ кешу «URL» не працює;
  • одна відповідь змішує дані з різним терміном актуальності (назва товару - години, залишок на складі - секунди).

Рішення на різних рівнях:

1. Нормалізований кеш на клієнті (Apollo Client, urql з Graphcache, Relay). Кеш зберігає об'єкти за __typename + id, а не відповіді цілком. Мутація, що повертає змінений об'єкт, автоматично оновлює його в усіх екранах. Тому корисно мати глобально унікальні ідентифікатори і завжди запитувати id.

2. Збережені запити + GET. Клієнт надсилає хеш заздалегідь відомого запиту і змінні в рядку запиту:

GET /graphql?extensions={"persistedQuery":{"sha256Hash":"ab12..."}}&variables={"id":42}

Тепер відповідь має стабільну адресу, і її можна кешувати на CDN - як REST.

3. Підказки кешування в схемі. Сервер обчислює Cache-Control для відповіді з найкоротшого терміну серед полів (директиви на кшталт @cacheControl(maxAge: 60)), а персональні поля позначає приватними. Відповідь з даними користувача не повинна потрапити в спільний кеш.

4. Кеш на сервері:

  • на рівні резолверів чи DataLoader - кешування окремих сутностей у Redis;
  • кеш цілих відповідей за нормалізованим текстом запиту + змінними + користувачем - простий, але інвалідація складна.

Інвалідація - найважче місце. Зміна одного товару торкається безлічі різних запитів, що його містять. Тому популярний підхід - теги: відповідь позначається тегами сутностей (Product:42), і зміна сутності скидає всі відповіді з цим тегом (так працюють CDN з purge за ключами).

Практичний висновок: якщо важливий кеш на CDN для публічних даних (каталог, статті), - або REST для цих частин, або збережені запити через GET. Для персональних даних основну роботу робить нормалізований кеш клієнта.

Докладніше в документації: Кешування в GraphQL

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання