Стратегии для API-запросов

Workbox предоставляет гибкие инструменты для управления кешированием и маршрутизацией сетевых запросов. При работе с API важно выбирать стратегию, которая обеспечит баланс между актуальностью данных и скоростью отклика. Ниже рассматриваются основные стратегии, применимые к REST API и GraphQL.


Cache First

Описание: При использовании стратегии Cache First сервис-воркер сначала ищет ответ в кешe. Если данные не найдены, выполняется сетевой запрос, после чего ответ сохраняется в кеш.

Применение: Подходит для нечасто изменяющихся данных, таких как справочники, списки категорий или статические настройки.

Пример с Workbox:

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/static/'),
  new CacheFirst({
    cacheName: 'api-static-cache',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 24 * 60 * 60, // 1 день
      }),
    ],
  })
);

Ключевые моменты:

  • Быстрый отклик при повторных запросах.
  • Не подходит для динамических данных.
  • Необходим контроль устаревших данных через maxAgeSeconds.

Network First

Описание: Стратегия Network First сначала выполняет сетевой запрос. Если он успешен, ответ сохраняется в кеш. При недоступной сети данные берутся из кеша.

Применение: Подходит для динамических данных, таких как пользовательские профили, ленты новостей или результаты поиска.

Пример с Workbox:

import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/user/'),
  new NetworkFirst({
    cacheName: 'api-user-cache',
    networkTimeoutSeconds: 5, // fallback к кешу, если сеть не отвечает
    plugins: [
      new ExpirationPlugin({
        maxEntries: 100,
        maxAgeSeconds: 60 * 60, // 1 час
      }),
    ],
  })
);

Ключевые моменты:

  • Гарантирует актуальность данных при онлайн-доступе.
  • Сетевой таймаут позволяет работать в оффлайн-режиме.
  • Более медленная отдача данных по сравнению с Cache First.

Stale While Revalidate

Описание: Стратегия Stale While Revalidate возвращает кешированный ответ сразу, а затем выполняет сетевой запрос для обновления кеша.

Применение: Оптимальна для данных, где важна скорость отклика, но допустимо, что данные будут немного устаревшими, например, новости, уведомления или API сторонних сервисов.

Пример с Workbox:

import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/news/'),
  new StaleWhileRevalidate({
    cacheName: 'api-news-cache',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 200,
        maxAgeSeconds: 30 * 60, // 30 минут
      }),
    ],
  })
);

Ключевые моменты:

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

Cache Only и Network Only

Описание:

  • Cache Only — данные берутся исключительно из кеша. Используется для статических ответов.
  • Network Only — данные всегда загружаются с сервера, кеш не используется. Полезно для критически актуальных данных, таких как финансовые транзакции.

Пример:

import { CacheOnly, NetworkOnly } from 'workbox-strategies';

registerRoute(
  ({ url }) => url.pathname.endsWith('/config.json'),
  new CacheOnly({ cacheName: 'config-cache' })
);

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/transactions/'),
  new NetworkOnly()
);

Ключевые моменты:

  • Cache Only исключает сетевые задержки, но требует предзагрузки кеша.
  • Network Only гарантирует актуальность, но не работает в оффлайне.

Настройка кеша и стратегий для API

ExpirationPlugin позволяет ограничить:

  • maxEntries — максимальное количество объектов в кеше
  • maxAgeSeconds — время жизни данных

CacheableResponsePlugin помогает кешировать только успешные ответы:

import { CacheableResponsePlugin } from 'workbox-cacheable-response';

new CacheableResponsePlugin({
  statuses: [0, 200], // кешировать только успешные ответы
});

Советы по применению:

  • Комбинировать стратегии для разных эндпоинтов API.
  • Не кешировать чувствительные данные без шифрования.
  • Настраивать networkTimeoutSeconds при Network First для балансировки оффлайн-доступа и актуальности.

Примеры комбинирования стратегий

Для приложения с разделением данных на статические справочники, пользовательский контент и новостные ленты:

// Статические справочники
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/static/'),
  new CacheFirst({ cacheName: 'static-cache' })
);

// Пользовательские данные
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/user/'),
  new NetworkFirst({ cacheName: 'user-cache', networkTimeoutSeconds: 5 })
);

// Новости
registerRoute(
  ({ url }) => url.pathname.startsWith('/api/news/'),
  new StaleWhileRevalidate({ cacheName: 'news-cache' })
);

Такое распределение стратегий обеспечивает оптимальное сочетание скорости, актуальности и оффлайн-доступа.