Skip to content

REST-клиент ​

createRestClient():

ts
createRestClient(config: HttpConfig): RestClient

Создаёт полнофункциональный HTTP-клиент поверх axios: повторы, кэширование ответов, ограничение частоты запросов, circuit breaker, провайдер аутентификации, трассировка запросов, ключи идемпотентности и очередь офлайн-запросов — всё опционально через HttpConfig.

Методы ​

get(url, config?) ​

GET-запрос.

post(url, data?, config?) ​

POST-запрос.

put(url, data?, config?) ​

PUT-запрос.

patch(url, data?, config?) ​

PATCH-запрос.

delete(url, config?) ​

DELETE-запрос.

request(url, config?) ​

Универсальный запрос.

cancellableRequest(key, url, config?) ​

Запрос, отменяемый по key.

cancelRequest(key) ​

Отменить запрос, ранее сделанный через cancellableRequest(key, ...).

clearCache() ​

Очистить весь кэш ответов клиента. async.

invalidateCache(matcher) ​

Очистить только те записи кэша, чей URL совпадает с matcher (подстрока, RegExp или (info) => boolean). Возвращает Promise<number> — количество удалённых записей. См. Точечная инвалидация кэша ниже.

getCircuitBreakerState() ​

Promise<"closed" | "open" | "half-open" | null> — null, если circuitBreaker не настроен. Резолвится синхронно (без реальной асинхронной работы), если не задан circuitBreaker.store.

getQueuedRequests() ​

Promise<QueuedRequest[]> — запросы, ожидающие следующего сброса офлайн-очереди (пусто, если offlineQueue не настроен).

flushQueue() ​

Вручную попытаться отправить всё, что в очереди (также происходит автоматически при восстановлении связи). No-op, если offlineQueue не настроен.

Опции ​

HttpConfig — все поля опциональны, если не указано иное.

baseURL ​

string

Базовый URL для всех запросов.

timeout ​

number

Таймаут запроса в мс.

headers ​

Record<string, string>

Заголовки по умолчанию для каждого запроса.

withCredentials ​

boolean

Включать cookies на кросс-доменных запросах.

retry ​

RetryConfig

Повторные попытки с экспоненциальным backoff. См. RequestExecutor — класс, который на самом деле реализует повторы и для createRestClient(), и для отдельного использования.

ПолеОписание
attemptsКоличество повторных попыток
delayMsБазовая задержка между попытками в мс
backoffMultiplierМножитель экспоненциального backoff
retriableStatusHTTP-коды статуса, при которых допустим повтор (например, [429, 500, 503])
maxRetryAfterMsМаксимальное время ожидания по заголовку Retry-After в мс (по умолчанию: 60000)
jitterStrategyАлгоритм jitter для backoff — см. Стратегии jitter

cache ​

CacheConfig

Кэширование ответов для GET-запросов.

ПолеОписание
enabledВключить кэширование ответов
ttlMsTTL кэша в мс
strategy"strict" (по умолчанию) или "stale-while-revalidate"
staleMsДополнительное время после ttlMs, в течение которого может отдаваться устаревший ответ (SWR)
storeКастомный backend CacheStore — см. Пользовательский backend кэша ниже

rateLimit ​

RateLimitConfig

Ограничение частоты по конкурентности и запросам за интервал.

ПолеОписание
maxConcurrentМаксимум одновременных запросов
maxRequestsPerIntervalМаксимум запросов за временное окно
intervalMsРазмер временного окна в мс
storeКастомный backend RateLimiterStore — см. Распределённое ограничение частоты запросов
keyИмя бакета при использовании общего store (по умолчанию: случайный id для каждого инстанса — без явного key у store нет эффекта общего использования)
leaseMsАвтоматическое истечение (мс) для слота конкурентности на базе store, если его владелец упал без освобождения (по умолчанию: 30000)
onRateLimitHeadersКоллбэк с сырыми заголовками каждого ответа — см. Проактивное ограничение скорости

metrics ​

MetricsConfig

ПолеОписание
onRequestStartКоллбэк при старте запроса
onRequestEndКоллбэк по завершении запроса (включает длительность и количество байт)

auth ​

AuthConfig

Вставка Bearer-токена с автоматическим обновлением по 401. См. Провайдер аутентификации за полным описанием поведения и примером.

ПолеОписание
getTokenАсинхронная функция, возвращающая Bearer-токен (вызывается перед каждым запросом, если не задан tokenTtlMs)
onUnauthorizedОпциональный асинхронный коллбэк на 401 — здесь обновляйте токен; запрос повторяется один раз
tokenTtlMsКэшировать результат getToken() на это количество мс вместо вызова перед каждым запросом; сбрасывается автоматически при 401

sanitizeHeaders ​

boolean · default: true

Маскировать чувствительные заголовки в коллбэках метрик (безопасно по умолчанию). См. Санитизация логов.

sensitiveHeaders ​

string[]

Дополнительные заголовки для маскирования, расширяет DEFAULT_SENSITIVE_HEADERS.

adapter ​

HttpAdapter

Кастомный HTTP-адаптер (например, нативный fetch) — заменяет встроенный транспорт axios. См. HTTP-адаптер.

circuitBreaker ​

CircuitBreakerConfig

См. Circuit breaker.

ПолеОписание
failureThresholdКоличество последовательных провалов до открытия цепи
openMsСколько цепь остаётся открытой перед следующей пробой
successThresholdСколько успешных проб нужно для полного закрытия (опционально)
isFailureПредикат, решающий, считать ли ошибку провалом (опционально)
storeКастомный CircuitBreakerStore для общего состояния между инстансами (опционально)
keyИмя общего бакета при использовании store (опционально)

tracing ​

TracingConfig

См. Трассировка запросов.

ПолеОписание
generateTraceparentДобавлять заголовок W3C traceparent к каждому запросу (по умолчанию: false)
providerХук TracingProvider, создающий span на каждый запрос

idempotencyHeaderName ​

string · default: "Idempotency-Key"

Имя заголовка, используемое для RestRequestConfig.idempotencyKey. См. Ключи идемпотентности.

autoIdempotencyKey ​

boolean · default: false

Заставить RequestExecutor автоматически генерировать ключ идемпотентности на логический запрос. См. Ключи идемпотентности.

offlineQueue ​

OfflineQueueConfig

См. Очередь офлайн-запросов.

ПолеОписание
enabledВключить офлайн-очередь
persistAdapterПара save/load для запросов в очереди
isOnlineФункция, сообщающая текущую связность (по умолчанию: navigator.onLine)
onOnlineChangeПодписка на изменения связности (по умолчанию: браузерное событие "online")
shouldQueueКакие запросы ставятся в очередь (по умолчанию: изменяющие методы — POST/PUT/PATCH/DELETE)
maxQueueSizeОграничение размера очереди
onFlushSuccessКоллбэк при успешном повторе запроса из очереди
onFlushErrorКоллбэк при окончательном провале запроса из очереди

Переопределение кэша для отдельного запроса ​

js
const res = await client.get('/data', {
  useCache: true,
  cacheTtlMs: 30000,
  cacheKey: 'my-custom-key',
})

Загрузка файлов и прогресс ​

RestRequestConfig расширяет собственный AxiosRequestConfig из axios, поэтому data может быть FormData/Blob/ArrayBuffer, а onUploadProgress/onDownloadProgress уже типизированы и подключены — никакой дополнительной настройки для транспорта по умолчанию (axios) не требуется:

js
const formData = new FormData()
formData.append('file', fileInput.files[0])

await client.post('/upload', formData, {
  onUploadProgress: (event) => {
    const percent = event.total ? Math.round((event.loaded / event.total) * 100) : 0
    console.log(`Uploaded ${percent}%`)
  },
})

await client.get('/large-report.csv', {
  responseType: 'blob',
  onDownloadProgress: (event) => console.log(event.loaded, 'bytes received'),
})

При использовании кастомного adapter (см. HTTP-адаптер) вместо встроенного транспорта axios onUploadProgress/onDownloadProgress всё равно передаются в объект config вашего адаптера как есть, но за их фактический вызов отвечает сам адаптер — у fetch нет нативного события прогресса загрузки, поэтому адаптеру на fetch для этого понадобится читатель ReadableStream (либо XMLHttpRequest). См. examples/file-upload.ts.

Точечная инвалидация кэша ​

clearCache() стирает весь кэш ответов целиком. Чтобы инвалидировать только записи, затронутые мутацией (например, после POST/PUT/DELETE), используйте вместо этого invalidateCache() — она принимает подстроку, RegExp или предикат над { method, url } и возвращает количество удалённых записей. Оба метода async (чтобы кастомный cache.store мог быть на реальном сетевом вызове):

js
await client.post('/users/1/orders', newOrder)

await client.invalidateCache('/users/1') // совпадение по подстроке в кэшированном URL
await client.invalidateCache(/^https:\/\/api\.example\.com\/users\/\d+$/)
await client.invalidateCache(({ method, url }) => method === 'GET' && url.includes('/orders'))

Пользовательский backend кэша (CacheStore) ​

По умолчанию cache.enabled: true кэширует ответы в in-memory TtlCache, привязанном к конкретному экземпляру клиента — нормально для браузерного SPA, но в развёртывании с несколькими инстансами у каждого серверного процесса свой холодный кэш. Передайте cache.store, чтобы использовать любой backend, реализующий CacheStore — например, Redis, чтобы кэшированные ответы были общими для всех инстансов:

ts
import { createRestClient, type CacheStore, type ApiResponse } from 'rest-pipeline-js'

const redisStore: CacheStore<ApiResponse<unknown>> = {
  async get(key) {
    const raw = await redis.get(key)
    return raw ? JSON.parse(raw) : undefined
  },
  async set(key, value, ttlMs) {
    await redis.set(key, JSON.stringify(value), 'PX', ttlMs)
  },
  async delete(key) {
    await redis.del(key)
  },
  async clear() {
    await redis.flushdb()
  },
  // getStale/deleteWhere опциональны — без них стратегия
  // 'stale-while-revalidate' и invalidateCache() корректно
  // деградируют (см. JSDoc для CacheStore) вместо выброса исключения.
}

const client = createRestClient({
  baseURL: 'https://api.example.com',
  cache: { enabled: true, ttlMs: 60_000, store: redisStore },
})

Полную аннотированную версию см. в examples/redis-cache-store.ts.

Полный пример ​

js
import { createRestClient } from 'rest-pipeline-js'

const client = createRestClient({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  retry: {
    attempts: 2,
    delayMs: 500,
    backoffMultiplier: 2,
    retriableStatus: [429, 500, 503],
  },
  cache: { enabled: true, ttlMs: 60000 },
  rateLimit: { maxConcurrent: 3, maxRequestsPerInterval: 10, intervalMs: 1000 },
  auth: {
    getToken: async () => localStorage.getItem('token') ?? '',
    onUnauthorized: async () => {
      /* здесь обновляем токен */
    },
  },
  sanitizeHeaders: true,
})

const res = await client.get('/users/1')
console.log(res.data)

// Поддержка PATCH
await client.patch('/users/1', { name: 'Alice' })

// Отменяемый запрос
const req = client.cancellableRequest('my-key', '/search', {
  params: { q: 'foo' },
})
// Отменить в любой момент:
client.cancelRequest('my-key')