sync
This commit is contained in:
124
OLD_parts/14-api-hooks.md
Normal file
124
OLD_parts/14-api-hooks.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# Хуки API (React Hooks)
|
||||
|
||||
> В проекте для работы с API-хуками используется только React и библиотека SWR для получения данных (GET-запросы).
|
||||
> В этом разделе собраны основные правила и рекомендации по созданию и оформлению хуков для работы с API. Следуйте этим принципам, чтобы обеспечить чистую архитектуру, переиспользуемость и единый стиль работы с API-хуками в проекте.
|
||||
|
||||
## Описание и назначение API-хуков
|
||||
|
||||
API-хуки предназначены для получения данных с сервера (GET-запросы) и используются в компонентах или других хуках.
|
||||
В проекте для этого применяется библиотека SWR, которая обеспечивает кэширование, автоматическое обновление и удобную работу с асинхронными запросами.
|
||||
|
||||
**Fetcher** — это функция, которую использует SWR для выполнения запроса к API. В проекте fetcher обычно экспортируется из файла клиента (например, `backendFetcher` из `shared/api/backend/client.ts`) и инкапсулирует логику обращения к конкретному API-клиенту.
|
||||
|
||||
**API-клиент** — это отдельный модуль (папка), отвечающий за взаимодействие с конкретным внешним или внутренним API.
|
||||
API-клиент включает:
|
||||
- инициализацию экземпляра HTTP-клиента (например, Axios),
|
||||
- настройку базового URL, интерцепторов и общих обработчиков ошибок,
|
||||
- организацию всех сущностей и методов для работы с этим API (например, users, auth, orders и т.д.),
|
||||
- экспорт всех функций, типов и fetcher через индексные файлы.
|
||||
|
||||
Каждый API-клиент размещается в папке `src/shared/api/<client-name>/` и имеет собственную структуру согласно архитектуре проекта.
|
||||
|
||||
## Структура
|
||||
- Каждый API-хук размещается в отдельном файле с именем `use-<method-name>.hook-api.ts` в папке `hooks/api/<client-name>/` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- Имя хука — в стиле camelCase с префиксом `use` (например, `useGetUser`).
|
||||
- Для сложных возвращаемых структур используйте отдельные типы или интерфейсы, размещая их в папке `types/` на своём уровне абстракции.
|
||||
|
||||
## Именование
|
||||
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
||||
- Файл хука — `use-<method-name>.hook-api.ts` (kebab-case).
|
||||
- Имя хука — camelCase с префиксом `use`.
|
||||
|
||||
## Требования
|
||||
- Хук должен быть строго типизирован: все параметры, возвращаемые значения и внутренние переменные должны иметь явные типы.
|
||||
- Для получения данных используйте только SWR.
|
||||
- Не дублируйте логику между хуками — общие части выносите в shared.
|
||||
- Не используйте side-effects вне useEffect/useLayoutEffect.
|
||||
|
||||
## Типизация
|
||||
- Всегда явно указывайте типы для всех параметров, возвращаемых значений и состояния внутри хука.
|
||||
- Придерживайтесь [общих правил типизации проекта](#общие-правила-типизации).
|
||||
- Не используйте неявное приведение типов и не полагайтесь на автоматический вывод, если это может снизить читаемость или безопасность.
|
||||
|
||||
## Документирование
|
||||
- Документируйте только назначение хука (описание), строго по [правилам документирования кода](#правило-для-документирования-кода).
|
||||
|
||||
## Экспорт
|
||||
- Экспортируйте хук только именованным экспортом через `index.ts` слоя/компонента.
|
||||
|
||||
## Пример API хука
|
||||
|
||||
```ts
|
||||
// use-get-me.hook-api.ts
|
||||
import useSWR from 'swr';
|
||||
import { backendFetcher } from 'shared/api/backend/client';
|
||||
import { UserDto } from 'shared/api/backend/entities/users/get-me.api';
|
||||
|
||||
/**
|
||||
* Хук для получения информации о текущем пользователе.
|
||||
*/
|
||||
export const useGetMe = () => {
|
||||
const { data, error, isLoading } = useSWR<UserDto>('/users/me', backendFetcher);
|
||||
|
||||
return {
|
||||
data,
|
||||
error,
|
||||
isLoading,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Пример использования хука в компоненте
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { useGetMe } from 'shared/hooks/api/backend/use-get-me.hook-api';
|
||||
|
||||
export const UserInfo: React.FC = () => {
|
||||
const { data, error, isLoading } = useGetMe();
|
||||
|
||||
if (isLoading) {
|
||||
return <div>Загрузка...</div>;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <div>Ошибка загрузки данных</div>;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <div>Нет данных о пользователе</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>Имя: {data.name}</div>
|
||||
<div>Email: {data.email}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Чек-лист для создания API-хука
|
||||
|
||||
- [ ] Для каждого GET-запроса создан отдельный хук.
|
||||
- [ ] Хук размещён в `hooks/api/<client-name>/use-<method-name>.hook-api.ts` на своём уровне абстракции согласно архитектуре проекта.
|
||||
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
|
||||
- [ ] Используется SWR для получения данных.
|
||||
- [ ] Все параметры, возвращаемые значения и внутренние переменные строго типизированы.
|
||||
- [ ] Нет дублирования логики между хуками.
|
||||
- [ ] Не используются side-effects вне useEffect/useLayoutEffect.
|
||||
- [ ] Документировано только назначение хука (см. [правила документирования кода](#правило-для-документирования-кода)).
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
- [ ] Экспорт только именованный через индексный файл.
|
||||
|
||||
---
|
||||
|
||||
## Чек-лист для использования API-хука
|
||||
|
||||
- [ ] Импортируется только нужный хук через публичные экспорты (`index.ts`).
|
||||
- [ ] Использование хука строго по назначению (только для получения данных).
|
||||
- [ ] Если требуется получить данные через GET-запрос в компоненте — обязательно используется соответствующий API-хук.
|
||||
**Запрещено вызывать GET-методы API напрямую в компонентах, только через хуки.**
|
||||
- [ ] Обработка состояний загрузки, ошибки и данных реализована корректно.
|
||||
- [ ] Не происходит дублирования логики, связанной с получением данных.
|
||||
- [ ] Нет неиспользуемого или невалидного кода.
|
||||
Reference in New Issue
Block a user