7.2 KiB
title, description, keywords
| title | description | keywords | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Кастомизация HTTP-клиента | Настройка транспорта REST-клиента через опции и хуки HttpClient. |
|
Кастомизация HTTP-клиента
Настройка транспорта REST-клиента через опции и хуки HttpClient.
Где живёт кастомизация
Вся настройка транспорта — baseUrl, заголовки, авторизация, retry — задаётся в client.ts REST-модуля при создании HttpClient.
Не размещайте авторизацию, обработку 401 и логирование в компонентах, GET-хуках или обёртках над операциями: у транспорта одна точка настройки.
В generated/SDK-сценарии HttpClient импортируется из generated-кода или SDK-пакета. В ручном сценарии без OpenAPI HttpClient импортируется из runtime-зависимости @gromlab/api-codegen.
import { HttpClient } from '@gromlab/api-codegen'
Опции HttpClient
HttpClient принимает плоский конфиг: стандартные fetch-опции задаются вместе с хуками клиента.
| Опция | Назначение |
|---|---|
baseUrl |
Базовый URL API. |
headers |
Заголовки по умолчанию для всех запросов. |
credentials |
Политика отправки cookies: omit, same-origin, include. |
timeout |
Таймаут запроса в миллисекундах, работает через AbortSignal. |
customFetch |
Замена стандартного fetch: тесты, SSR, custom transport. |
paramsSerializer |
Кастомная сериализация query params в URL. |
responseParser |
Кастомный парсинг response body. |
onRequest |
Request-хук перед вызовом fetch. |
onResponse |
Response-хук после успешного HTTP-ответа. |
onError |
Error-хук для HTTP-ошибок, network errors и ошибок парсинга. |
Полный список опций — в README @gromlab/api-codegen.
Контракт хуков
onRequest(params, context)вызывается передfetchи возвращает изменённыеparams.onResponse(response, context)вызывается после успешного ответа и возвращаетresponse.onError(error, context)вызывается для HTTP-ошибок, network errors и ошибок парсинга.contextсодержитurl,request,retryCountиretry()— повтор текущего запроса.onErrorдолжен либо бросить ошибку, либо вернуть fallback-значение, либо вернуть результатcontext.retry(). Если вернутьundefined, ошибка будет считаться обработанной, а вызывающий код получитundefinedвместо исключения.- Для защищённых endpoints generated operation передаёт
secure: true, поэтому авторизацию можно добавлять только там, где она нужна.
JWT-авторизация
Токен добавляется в onRequest только для защищённых запросов и не перезаписывает явно переданный Authorization.
// src/infra/pet-store-rest-api/client.ts
export const petStoreHttpClient = new HttpClient({
baseUrl: 'https://example.com/api',
onRequest: (params) => {
const token = localStorage.getItem('access_token')
if (!params.secure || !token) {
return params
}
const headers = new Headers(params.headers)
if (!headers.has('Authorization')) {
headers.set('Authorization', `Bearer ${token}`)
}
return {
...params,
headers,
}
},
})
Refresh token
Обновление токена и повтор запроса выполняются в onError через context.retry(). context.retryCount защищает от бесконечного цикла повторов.
// src/infra/pet-store-rest-api/client.ts
import { ApiError, HttpClient } from './generated'
export const petStoreHttpClient = new HttpClient({
baseUrl: 'https://example.com/api',
onError: async (error, context) => {
if (error instanceof ApiError && error.status === 401 && context.retryCount === 0) {
await refreshToken()
return context.retry()
}
throw error
},
})
ApiError экспортируется из generated/ и содержит status, statusText, response, data и исходный request.
Логирование
const petStoreHttpClient = new HttpClient({
baseUrl: 'https://example.com/api',
onResponse: (response, context) => {
console.log(context.request.method, context.url, response.status)
return response
},
})
Сериализация query params
const petStoreHttpClient = new HttpClient({
baseUrl: 'https://example.com/api',
paramsSerializer: (query) => {
const params = new URLSearchParams()
Object.entries(query).forEach(([key, value]) => {
if (Array.isArray(value)) {
params.set(key, value.join(','))
return
}
if (value !== undefined) {
params.set(key, String(value))
}
})
return params.toString()
},
})
Параметры одного вызова
Разовые настройки запроса не относятся к HttpClient. Они передаются последним аргументом operation:
import { getPetById } from './generated/operations/get-pet-by-id'
import { petStoreHttpClient } from './client'
await getPetById(
petStoreHttpClient,
{ petId },
{
headers: {
'X-Request-Id': requestId,
},
},
)
Правила
- Кастомизация транспорта живёт только в
client.tsREST-модуля. - Авторизация добавляется в
onRequestс учётомparams.secureи без перезаписи явногоAuthorization. onErrorлибо бросает ошибку, либо возвращает fallback илиcontext.retry(); молчаливыйreturnзапрещён.- Повторы запроса ограничиваются проверкой
context.retryCount. - Бизнес-реакции на ошибки — тосты, редиректы, UI-состояние — не размещаются в хуках
HttpClient.
Следующий шаг
После настройки транспорта проверьте использование REST-клиента или добавьте GET-хуки REST-клиента.