<!-- Canonical: https://docs.shopstory.live/docs/operations/caching -->

# Кэширование API

ShopStory не публикует единый TTL для всех endpoint и клиентских окружений. Ориентируйтесь на `Cache-Control` конкретного ответа и допустимый срок обновления данных в вашем интерфейсе.

## Что можно кэшировать

| Данные | Подход |
| --- | --- |
| Каталог стримов | Допустим короткий TTL, если интерфейс допускает небольшую задержку обновления |
| Состояние live или mini-player | Использовать срок, согласованный для конкретного сценария |
| Быстро меняющееся состояние трансляции | Запрашивать заново по умолчанию |
| Изменение корзины и проверка актуального остатка | Не кэшировать результат операции |
| Ошибка конфигурации или валидации | Не сохранять как успешный ответ |

## Состав cache key

Включите в ключ endpoint и каждый параметр, влияющий на ответ:

- `applicationId`;
- идентификатор товара, категории или трансляции;
- фильтр статуса;
- `limit` и `offset`;
- версию API.

`applicationId` не является секретом. Он разделяет данные клиентских окружений. Cache key без этого поля может вернуть контент другого клиента.

```text
GET /v3/streams
→ shopstory:v3:streams:{applicationId}:{feedProductId}:{status}:{categoryId}:{limit}:{offset}
```

Не составляйте ключ из непроверенной строки целиком. Нормализуйте разрешённые параметры и задайте максимальную длину.

## Общий кэш и пользовательские данные

- Не помещайте ответы с авторизацией или персонализацией в общий CDN-кэш без явно заданной модели private cache.
- Если ответ зависит от авторизации, одного `Vary: Authorization` обычно недостаточно, чтобы изолировать данные клиентов. Используйте private cache или backend-кэш с отдельным ключом для каждой области данных.
- Не кэшируйте cookies, CSRF-токены, изменения корзины и учётные данные merchant-системы.
- Не добавляйте секреты в cache key, URL, логи и метрики.

## Обновление данных

В backend-кэше задайте ограниченный TTL. Когда несколько запросов одновременно не находят один ключ в кэше, отправляйте upstream только один запрос. Сохраняйте старый каталог при ошибке upstream только если интерфейс допускает устаревшие данные. Не подтверждайте наличие товара или успешную покупку по устаревшим данным из кэша.

`serverTime` в JSON-конверте показывает время ответа. Он не задаёт правила кэширования.

## Проверка ответа до записи

cacheable-response.js

```javascript
async function readShopStory(url) {
  const response = await fetch(url, {
    headers: { Accept: 'application/json' },
    signal: AbortSignal.timeout(5000),
  });

  if (!response.ok) {
    throw new Error(`Transport error ${response.status}`);
  }

  const envelope = await response.json();
  if (envelope.status !== 200) {
    throw new Error(envelope.body?.message || 'ShopStory API error');
  }

  return envelope;
}
```

Записывайте в кэш только проверенный успешный ответ. Поведение временных ошибок описано в разделе [Rate limiting](<https://docs.shopstory.live/docs/operations/rate-limits>).
