Files
2026-08-01 09:31:08 +03:00

8.6 KiB
Raw Permalink Blame History

title, description, keywords
title description keywords
Настройка REST-клиента Подготовка REST-клиента сервиса к использованию.
rest
клиент
infra
operation
openapi
get-хуки
swr

Настройка 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-клиент состоит из четырёх основных частей:

  1. Транспорт — ручной client.ts с настроенным *HttpClient.
  2. Полный API-клиентrest-api.ts с createApiClient(*HttpClient, operationsTree).
  3. Операции — operation-функции, сгенерированные из OpenAPI, поставляемые SDK-пакетом или написанные вручную через @gromlab/api-codegen.
  4. GET-хуки — SWR-обёртки для GET-запросов.

Эти части живут в одном REST-модуле, потому что относятся к одному внешнему сервису.

Транспорт

client.ts — ручной слой, который настраивает транспорт: HttpClient, заголовки, авторизацию и обработку ошибок.

Авторизация, refresh token и другие транспортные сценарии настраиваются хуками HttpClientonRequest, 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.

Что делаем дальше

  1. Создайте операции клиента: Автогенерация из OpenAPI, SDK-пакет или Ручное создание.
  2. Если клиент нужен нескольким приложениям, вынесите generated-код в пакет: SDK-пакет REST-клиента.
  3. Настройте транспорт — авторизацию, хуки, таймауты: Кастомизация HTTP-клиента.
  4. Добавьте GET-хуки для GET-запросов: GET-хуки REST-клиента.
  5. Проверьте прямые вызовы клиента: Использование REST-клиента.
  6. После настройки клиента выбирайте стратегию route-level data fetching по nextjs-style-guide.