Кэш API: свежесть, изоляция и согласованность

Кратко

Кэш экономит работу и обмены повторным использованием ответа. Польза зависит от ключей, прав, допустимого возраста и поведения при недоступности источника.

Стойки связи и сетевые кабели в пустом техническом помещении
В этой статье

Разделять прикладной и HTTP-кэш

Redis, Workers KV и HTTP-кэши не имеют автоматически одинаковых гарантий. Workers KV согласован в конечном счёте: запись не сразу видна везде. Следующие директивы относятся к HTTP и сами по себе не настраивают прикладной кэш.

Директива ответа HTTPОсновной смыслОграничение
no-cacheХранение возможно, перед повторным использованием нужна проверка.Не означает запрет хранения.
no-storeНе хранить этот ответ в кэшах.Не удаляет прежние копии автоматически.
privateНе хранить в общем кэше.Не правило аутентификации.
max-ageСрок свежести ответа.Не гарантирует согласованность всех данных.

Проверять правильный ответ нужному человеку

  • Задайте вариации ключа по ресурсу, параметрам, языку и правам. Убедитесь, что аккаунт не получает частный ответ другого.
  • Опишите максимальный возраст, инвалидацию и поведение после изменения или удаления. Короткий TTL не гарантирует немедленно согласованное чтение.
  • Тестируйте одновременное истечение, сбой кэша и источника. Объединяйте обновления при необходимости и выдавайте устаревшее только по допустимым бизнес-правилам.

Измерять больше, чем долю попаданий

Следите за задержкой, ошибками, нагрузкой источника и неверными или устаревшими ответами. Баланс, зарезервированный запас и права могут требовать иных гарантий, чем открытый каталог. Быстрый кэш не должен стать бесконтрольным альтернативным источником истины.

Первоисточники

Кэширование API должно сохранять решения о доступе.

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

  • Классифицируйте общедоступные, закрытые и зависимые от роли поля перед кэшированием.
  • Проверьте ответ под одной учетной записью и запросите его под другой.
  • Аннулируйте результаты после изменения разрешений или данных.

Первичный источник: OWASP — GraphQL Cheat Sheet. Связанный метод: прочитать практическое руководство.

Измерять свежесть кэша наряду со скоростью

Вымышленный пример: данные не описывают клиента или наблюдаемый результат.

Два чтения быстрые, но одно показывает прежнюю доступность после изменения источника.

  • Сравнить значение, версию, точку чтения и время после изменения. Проверить инвалидирование, истечение срока и обращение к источнику по контракту системы.
  • Определить допустимое устаревание для каждого применения и отслеживать расхождения. Малая задержка не доказывает согласованность выдаваемых данных.

Первичный источник: IETF — RFC 9111, HTTP Caching. Связанный метод: прочитать практическое руководство.

Заброшенные поддомены: контролируемое удаление CNAME

Свяжите DNS-имена с подконтрольными ресурсами и закройте зависимости до освобождения сервиса.

  • Запишите имя, цепочку CNAME, ресурс поставщика и ответственного. Сопоставьте DNS с инвентарём разрешённой учётной записи. Ошибка HTTP, NXDOMAIN или отсутствие ресурса требуют проверки, но не доказывают возможность захвата; защиты поставщиков различаются.
  • Удалите ссылку или направьте её на подконтрольную цель до освобождения ресурса. Учтите прежние TTL и кэши; проверьте авторитетный DNS и несколько резолверов. Сохраните нужные проверки владения, не удаляйте все TXT подряд.
  • Проверьте ссылки, перенаправления, callback OAuth, вебхуки и домены cookie. Если ресурс уже освобождён, исправьте DNS и исследуйте возможное раскрытие по процедуре инцидента. Сверяйте DNS и ресурсы после каждого удаления.

Воспроизводимый приёмочный случай

Вымышленный пример: данные не описывают клиента или наблюдаемый результат.

Посмотреть данные случая
{
    "name": "portal.example",
    "cname_present": true,
    "resource_deleted": true,
    "provider_claimability": "not_verified",
    "takeover_observed": false,
    "expected": "remove_or_replace_mapping_and_review_exposure"
}

Ожидаемое решение

Вымышленный пример: portal.example указывает на удалённый ресурс. Удалите CNAME или используйте подконтрольную цель; отсутствие ресурса не доказывает захват третьей стороной.

Microsoft — Prevent dangling DNS entries

Доказывает ли страница ошибки возможность захвата?

Нет. Подтвердите состояние ресурса и правила резервирования или проверки владения. Не регистрируйте ресурс для демонстрации риска.

Первичный источник: Microsoft — Prevent dangling DNS entries. Связанный метод: прочитать практическое руководство.

ETag, HTTP-кеш и параллельные изменения

Подробные справочные заметки в этой версии доступны на английском.

Revalidation does not replace cache isolation

A matching If-None-Match can justify 304 for the selected representation after access checks. It does not by itself select the correct user variant.

  • Separate variant selection, authorisation and validator comparison.
  • Test weak and strong tags with If-None-Match: the comparison is weak.
  • Read no-cache as validation before reuse, rather than no-store.

Explore ETag comparisons and the simulator →

References reviewed · RFC 9110 · §13 · RFC 9111 · RFC 6585 · §3

GraphQL: ошибки, списки и частичные данные

Подробные справочные заметки в этой версии доступны на английском.

GraphQL result: follow the error path

Aliases belong to the result; list indices start at zero. These details determine where a client should flag missing data.

  • Compare absent data, partial data and data: null.
  • Keep the original path even when a parent becomes null.
  • Test permissions, quotas and interface states separately.

Explore GraphQL responses and nullability →

GraphQL Specification · September 2025 · Published edition · September 2025