import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/functional/# Хуки для работы с API'/>

# Хуки для работы с API

Набор инструментов для эффективного взаимодействия с бекендом, полностью интегрированный с **Vue 3 (Composition API)**.

## Особенности

Главная задача этих инструментов — автоматизировать рутинные задачи: отслеживание состояния загрузки (`loading`), обработку ошибок и синхронизацию данных между различными частями интерфейса. Все хуки поддерживают реактивные параметры, что позволяет создавать динамические запросы, которые сами обновляются при изменении входных фильтров или путей.

## Доступные инструменты

- `useApiRef` — Реактивное получение данных (GET) с автоматическим запуском и хранением в `ref`.
- `useApiAsyncRef` — Асинхронная версия `useApiRef` для немедленной инициализации (SSR).
- `useApiRequest` — Базовый хук для ручного выполнения любых HTTP-запросов (возвращает метод `send`).
- `useApiPost / Put / Delete` — Специализированные обертки для мутаций (создание, обновление, удаление).
- `useApiManagementRef` — Комплексный оркестратор, объединяющий GET-запросы, поиск, форматирование и мутации в единый цикл.
- `useApiManagementAsyncRef` — Асинхронный оркестратор для немедленной инициализации (SSR).

## Как с ними работать

Для простого отображения данных достаточно использовать `useApiRef`. Вам не нужно вручную вызывать функцию загрузки — запрос выполнится автоматически, как только вы обратитесь к свойству `data`. Если путь к API является реактивной ссылкой, хук сам отследит ее изменение и загрузит новые данные.

```typescript
import { useApiRef } from '@dxtmisha/functional'

// Данные загрузятся автоматически при обращении к data
const { data, loading } = useApiRef('api/profile')
```

Если же вам нужно выполнить действие по событию (например, сохранить форму), используются хуки для мутаций. Они возвращают метод `send`, который можно вызвать в обработчике события, и флаг `loading` для блокировки кнопок.

```typescript
import { useApiPost } from '@dxtmisha/functional'

const { send, loading } = useApiPost('api/save')

const onSave = async () => {
  await send({ data: { name: 'Dxt' } })
}
```

## useApiManagementRef

Самый мощный подход — это использование `useApiManagementRef`. Это полноценный хаб для управления данными в сложных интерфейсах (например, в таблицах). Он связывает GET-запрос с мутациями: как только вы успешно выполните `sendDelete` или `sendPost`, оркестратор сам вызовет `reset()` для основного списка, и данные на экране обновятся автоматически.

### Основные возможности:
- **Автоматизация**: Полная синхронизация между чтением и изменением данных.
- **Интеграция**: Включает в себя функционал поиска (`useSearchRef`) и форматирования (`useFormattersRef`).
- **Skeleton**: Поддержка заглушек на время загрузки для предотвращения «прыжков» интерфейса.
- **Гибкость**: Настройка индивидуальных путей и трансформаций для каждого типа запроса (GET, POST, PUT, DELETE).

```typescript
import { ref } from 'vue'
import { useApiManagementRef } from '@dxtmisha/functional'

const search = ref('')
const { 
  list, 
  sendPost, 
  sendDelete 
} = useApiManagementRef(
  { path: 'api/items' },      // Слушаем GET
  undefined,                  // Форматтеры
  { columns: ['name'], value: search }, // Живой поиск
  { path: 'api/items/add' },  // Настройка POST
  undefined,
  { path: 'api/items/delete' } // Настройка DELETE
)

// После вызова sendDelete() основной список list обновится САМ!
```

## Работа с ошибками

Хуки API используют систему управления ошибками на основе контрактов. Вместо того чтобы вручную обрабатывать каждый статус ответа в компонентах, вы определяете «базу» ожидаемых ошибок, и система разрешает их автоматически.

### Процесс работы:
1.  **Определение контракта (`errorContract`)**: Вы передаете хуку список возможных шаблонов ошибок (контракт). Это служит вашей базой данных для ошибок, которые требуют специфической обработки.
2.  **Автоматическое сопоставление**: Если запрос завершается неудачей (статус ≥ 400), система сравнивает ответ с вашим контрактом. Сопоставление происходит по следующим критериям:
    *   **HTTP-статус**: например, `404` или `500`.
    *   **Код ошибки**: специфический строковый код, извлеченный из JSON-тела ответа (например, `'USER_NOT_FOUND'`).
    *   **Шаблон URL**: конкретные эндпоинты или паттерны (RegExp).
    *   **Пользовательская валидация**: функция, которая возвращает `true`, если ответ соответствует ошибке.
3.  **Разрешение данных**: Если совпадение найдено, система заполняет реактивное свойство `errorItem` структурированными данными, включая локализованное сообщение и разрешенный код ошибки.
4.  **Реализация в UI**: В своем компоненте вы просто используете `errorItem` для отображения сообщений или переключения состояний интерфейса, будучи уверенными, что логика идентификации ошибок вынесена в контракт.

Эта система гарантирует, что ваши компоненты останутся чистыми и сфокусированными на логике отображения, в то время как идентификация ошибок остается декларативной и переиспользуемой.

## Работа в SSR

Все хуки для работы с API спроектированы с учетом поддержки **Server-Side Rendering (SSR)**. Чтобы данные были предзагружены на сервере до отправки страницы клиенту, у вас есть два варианта:

1.  **Асинхронные версии**: Используйте `useApiAsyncRef` или `useApiManagementAsyncRef`. Эти хуки автоматически вызывают `initSsr()` при создании, что гарантирует выполнение запроса во время серверного рендеринга.
2.  **Ручной вызов `initSsr()`**: Для стандартных хуков (например, `useApiRef`) необходимо явно вызвать метод `.initSsr()` внутри блока `setup()` компонента.

Это позволяет избежать «мерцания» контента (когда пользователь видит пустую страницу или скелетон, а затем данные подгружаются на клиенте) и улучшает SEO, предоставляя полностью заполненный HTML с сервера.

Такая архитектура позволяет описывать логику работы с данными декларативно, фокусируясь на конфигурации запросов, а не на ручном управлении состояниями загрузки и обновлении списков.
