8.6 KiB
title, description, keywords
| title | description | keywords | |||||||
|---|---|---|---|---|---|---|---|---|---|
| Настройка REST-клиента | Подготовка REST-клиента сервиса к использованию. |
|
Настройка REST-клиента
Подготовка REST-клиента сервиса к использованию.
Что настраиваем
REST-клиент — это infra-модуль, через который проект работает с внешним REST API.
На этапе настройки нужно подготовить транспортный HTTP-клиент, полный API-клиент и GET-хуки для клиентских компонентов.
Нейминг
- infra-модуль REST-клиента называется
{name}-rest-api:src/infra/pet-store-rest-api/. - Генерация внутри клиента — классический вариант — живёт в
{name}-rest-api/generated. - Если generated-клиент выносится в npm-пакет или пакет монорепозитория, пакет называется
{name}-rest-api-sdk: SDK-пакет REST-клиента. - Производные имена образуются от имени модуля: транспорт
petStoreHttpClient, полный API-клиентpetStoreRestApi, SWR-ключ['pet-store-rest-api', ...].
Из чего состоит клиент
REST-клиент состоит из четырёх основных частей:
- Транспорт — ручной
client.tsс настроенным*HttpClient. - Полный API-клиент —
rest-api.tsсcreateApiClient(*HttpClient, operationsTree). - Операции — operation-функции, сгенерированные из OpenAPI, поставляемые SDK-пакетом или написанные вручную через
@gromlab/api-codegen. - GET-хуки — SWR-обёртки для GET-запросов.
Эти части живут в одном REST-модуле, потому что относятся к одному внешнему сервису.
Транспорт
client.ts — ручной слой, который настраивает транспорт: HttpClient, заголовки, авторизацию и обработку ошибок.
Авторизация, refresh token и другие транспортные сценарии настраиваются хуками HttpClient — onRequest, onResponse, onError: Кастомизация HTTP-клиента.
Даже если операции генерируются из OpenAPI, client.ts остаётся ручным файлом проекта.
client.ts экспортирует только настроенный *HttpClient. В нём не размещаются DTO, declare module, Extended-типы, GET-хуки, operationsTree, createApiClient и бизнес-логика.
// src/infra/pet-store-rest-api/client.ts
import { HttpClient } from '@company/pet-store-rest-api-sdk'
export const petStoreHttpClient = new HttpClient({
baseUrl: 'https://example.com/api',
})
Полный API-клиент
rest-api.ts собирает полный bound API-клиент из всего generated дерева операций.
// src/infra/pet-store-rest-api/rest-api.ts
import { createApiClient } from '@company/pet-store-rest-api-sdk/create-api-client'
import { operationsTree } from '@company/pet-store-rest-api-sdk/operations-tree'
import { petStoreHttpClient } from './client'
export const petStoreRestApi = createApiClient(petStoreHttpClient, operationsTree)
Импортируйте operationsTree только в rest-api.ts. Для GET-хуков и minimal clients используйте точечные operation imports.
Операции
Операции описывают конкретные запросы к API.
Они появляются одним из трёх способов:
- генерируются из OpenAPI в
generated/как отдельные operation-функции; - поставляются SDK-пакетом
{name}-rest-api-sdk; - создаются вручную в
operations/через@gromlab/api-codegen, если OpenAPI нет или он неполный.
Подробности:
GET-хуки
Для GET-запросов добавляются GET-хуки REST-клиента.
Это прозрачные SWR-обёртки над generated GET operations. Они живут в hooks/ этого же REST-модуля и нужны для использования данных в Client Components.
GET-хуки именуются с префиксом useGet: useGetPetList, useGetPetDetail, useGetCurrentUser.
Каждый GET-хук имеет экспортируемую key-функцию. SWR-ключ всегда имеет формат [serviceName, endpoint]: например ['pet-store-rest-api', '/pet/10'].
Хук принимает generated-параметры операции и SWR-настройки: params?: GetPetByIdParams | null, config?: SWRConfiguration<Pet>.
hooks/index.ts содержит 'use client' и экспортирует все GET-хуки. Сами use-get-*.hook.ts остаются обычными файлами без директивы.
Подробности:
Структура модуля
src/infra/{name}-rest-api/
├── client.ts # настройка и экспорт *HttpClient
├── rest-api.ts # полный *RestApi через operationsTree
├── generated/ или operations/ # локальный split-клиент или ручные operations
├── operations-tree.ts # ручное дерево операций, если нет generated/operations-tree.ts
├── hooks/ # GET-хуки REST-клиента
│ ├── lib/
│ │ └── create-query-string.ts
│ ├── use-get-*.hook.ts
│ └── index.ts # 'use client' и публичные экспорты hooks
├── types/ # DTO, именованные response-типы и расширения типов
├── errors/ # ошибки API, если нужны
└── index.ts # публичный API
index.ts — единственная точка входа в REST-модуль для внешнего кода.
Если generated-код вынесен в {name}-rest-api-sdk, локальной папки generated/ внутри infra-модуля может не быть: client.ts, rest-api.ts и GET-хуки импортируют generated части из SDK subpath exports.
Если OpenAPI нет, не создавайте самописный fetch-класс и methods/. Ручной клиент пишется тем же API, что generated-клиент: HttpClient, ApiRequestClient, RequestParams, operation-функции и createApiClient из @gromlab/api-codegen.
Если generated operation возвращает безымянный тип вроде Record<string, number>, а этот тип нужен снаружи, вынесите его в types/. Не объявляйте DTO внутри hooks/use-get-*.hook.ts.
Что делаем дальше
- Создайте операции клиента: Автогенерация из OpenAPI, SDK-пакет или Ручное создание.
- Если клиент нужен нескольким приложениям, вынесите generated-код в пакет: SDK-пакет REST-клиента.
- Настройте транспорт — авторизацию, хуки, таймауты: Кастомизация HTTP-клиента.
- Добавьте GET-хуки для GET-запросов: GET-хуки REST-клиента.
- Проверьте прямые вызовы клиента: Использование REST-клиента.
- После настройки клиента выбирайте стратегию route-level data fetching по
nextjs-style-guide.