('/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 Загрузка...
;
}
if (error) {
return Ошибка загрузки данных
;
}
if (!data) {
return Нет данных о пользователе
;
}
return (
Имя: {data.name}
Email: {data.email}
);
};
```
### Чек-лист для создания API-хука
- [ ] Для каждого GET-запроса создан отдельный хук.
- [ ] Хук размещён в `hooks/api//use-.hook-api.ts` на своём уровне абстракции согласно архитектуре проекта.
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
- [ ] Используется SWR для получения данных.
- [ ] Все параметры, возвращаемые значения и внутренние переменные строго типизированы.
- [ ] Нет дублирования логики между хуками.
- [ ] Не используются side-effects вне useEffect/useLayoutEffect.
- [ ] Документировано только назначение хука (см. [правила документирования кода](#правило-для-документирования-кода)).
- [ ] Нет неиспользуемого или невалидного кода.
- [ ] Экспорт только именованный через индексный файл.
---
### Чек-лист для использования API-хука
- [ ] Импортируется только нужный хук через публичные экспорты (`index.ts`).
- [ ] Использование хука строго по назначению (только для получения данных).
- [ ] Если требуется получить данные через GET-запрос в компоненте — обязательно используется соответствующий API-хук.
**Запрещено вызывать GET-методы API напрямую в компонентах, только через хуки.**
- [ ] Обработка состояний загрузки, ошибки и данных реализована корректно.
- [ ] Не происходит дублирования логики, связанной с получением данных.
- [ ] Нет неиспользуемого или невалидного кода.
## API
> В этом разделе собраны основные правила и рекомендации по созданию, оформлению и использованию API-клиентов и функций для работы с сервером. Следуйте этим принципам, чтобы обеспечить единый стиль, безопасность и удобство поддержки API-слоя в проекте.
### Описание и назначение API-клиента
API-клиент — это модуль (папка), отвечающий за взаимодействие с конкретным внешним или внутренним API.
В проекте для HTTP-запросов используется только Axios.
API-клиент инкапсулирует:
- инициализацию экземпляра Axios,
- настройку базового URL, интерцепторов, обработчиков ошибок,
- организацию всех сущностей и методов для работы с этим API (например, users, auth, orders и т.д.),
- экспорт всех функций, типов и fetcher через индексные файлы.
Каждый API-клиент размещается в папке `src/shared/api//` и имеет собственную структуру согласно архитектуре проекта.
---
### Использование методов API
- Все методы API должны использоваться строго внутри блока `try...catch`.
- При вызове методов API всегда используйте полный путь, например:
`await api.backend.createUser({ email, password });`
- Запрещено вызывать методы API вне блока `try...catch` даже в тестах, утилитах и других вспомогательных функциях.
---
### Структура клиента
```text
src/shared/api/backend/
│
├── client.ts
├── index.ts
└── entities/
├── users/
│ ├── get-me.api.ts
│ ├── create-user.api.ts
│ ├── update-user.api.ts
│ └── index.ts
├── auth/
│ ├── login.api.ts
│ ├── register.api.ts
│ └── index.ts
└── index.ts
```
### Описание ключевых элементов
- **client.ts**
Экземпляр Axios с настройками, интерцепторами, экспортом fetcher для SWR.
- **index.ts**
Главная точка экспорта: экспортирует client, fetcher, все сущности и их методы.
- **entities/**
Папка для бизнес-сущностей (например, users, auth, orders и т.д.).
- **/**
Папка для отдельной сущности. Имя — в kebab-case, отражает бизнес-область (например, users, auth).
- **.api.ts**
Файл для каждой операции (CRUD, спец. действия).
Внутри:
- DTO (интерфейсы запроса/ответа)
- Функция, реализующая запрос через client
- **index.ts (внутри /)**
Экспортирует все методы и типы этой сущности.
- **index.ts (внутри entities/)**
Экспортирует все сущности (users, auth и т.д.).
---
### Именование
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
- Файл клиента — `client.ts`.
- Файл функции — `-.api.ts` (например, `create-user.api.ts`).
- DTO — в папке `dto/` (например, `create-user.dto.ts`).
- Все функции и типы экспортируются через индексные файлы на каждом уровне (сущность, entities, клиент).
---
### Требования
- Для каждого действия (CRUD, спец. действия) — отдельная функция и файл.
- Все функции используют общий экземпляр Axios из `client.ts`.
- Все функции строго типизированы (используются DTO).
- DTO объявляется в отдельном файле в папке `dto/` перед функцией, которая его использует.
- Для каждого GET метода обязательно должен быть создан API-хук.
- Все API-хуки должны создаваться строго по [документации раздела "Хуки для API"](#хуки-для-api-api-hooks).
---
### Типизация
- Все функции и DTO строго типизированы.
- Все интерфейсы, типы и enum размещены в папке `types/` на своём уровне абстракции.
- Все DTO размещены в папке `dto/` на своём уровне абстракции.
- Придерживайтесь [общих правил типизации проекта](#общие-правила-типизации).
---
### Документирование
- Документируйте только назначение функций и DTO, строго по [правилам документирования кода](#правило-для-документирования-кода).
- В описании указывается только смысл функции/типа.
---
### Экспорт
- Все функции и типы экспортируются через индексные файлы на каждом уровне (сущность, entities, клиент).
---
### Примеры
#### Пример клиента API
```ts
// client.ts
import axios, { AxiosInstance } from "axios";
export { AxiosError, isAxiosError } from 'axios';
export type { AxiosResponse } from 'axios';
/**
* Экземпляр HTTP-клиента для работы с backend API.
*/
export const backendHttpClient: AxiosInstance = axios.create({
baseURL: '/api',
timeout: 10000,
});
// Интерцептор запроса
backendHttpClient.interceptors.request.use(
(config) => {
// Здесь можно добавить авторизационные заголовки или другую логику
return config;
},
(error) => Promise.reject(error)
);
// Интерцептор ответа
backendHttpClient.interceptors.response.use(
(response) => response,
(error) => {
// Здесь можно обработать ошибки (например, показать уведомление)
return Promise.reject(error);
}
);
```
#### Пример DTO
```ts
// dto/create-user.dto.ts
/**
* DTO для создания пользователя.
*/
export interface CreateUserDto {
/** Email пользователя. */
email: string;
/** Пароль пользователя. */
password: string;
}
```
#### Пример API-функции
```ts
// create-user.api.ts
import { backendHttpClient } from '../client';
import { CreateUserDto } from './dto/create-user.dto';
/**
* Создать пользователя.
*/
export const createUser = (data: CreateUserDto) =>
backendHttpClient.post('/users', data);
```
#### Пример index.ts (в папке сущности)
```ts
export * from './create-user.api';
export * from './get-user.api';
```
#### Пример использования API-функции в компоненте
```tsx
import React, { useState } from 'react';
import { api } from 'shared/api';
export const CreateUserForm: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
await api.backend.createUser({ email, password });
console.log('Пользователь создан!');
} catch {
console.log('Ошибка создания пользователя');
}
};
return (
);
};
```
---
### Чек-лист для создания клиента
- [ ] Новый клиент размещён в src/shared/api//.
- [ ] В корне клиента есть client.ts (экземпляр Axios) и index.ts (главный экспорт).
- [ ] Все бизнес-сущности размещены в entities/, каждая — в отдельной папке.
- [ ] Для каждой операции создан отдельный файл .api.ts с DTO и функцией.
- [ ] DTO объявлен непосредственно перед функцией.
- [ ] В каждой папке сущности есть свой index.ts для экспорта методов и типов.
- [ ] В папке entities/ есть общий index.ts для экспорта всех сущностей.
- [ ] Все экспорты организованы через индексные файлы.
- [ ] Для каждого GET-метода создан отдельный SWR-хук (см. правила API-хуков).
- [ ] Нет дублирования кода и неиспользуемых файлов.
### Чек-лист для использования API
- [ ] Импортируется только нужный метод через публичные экспорты (index.ts).
- [ ] Все вызовы API обёрнуты в try...catch.
- [ ] Используются только строго типизированные методы.
- [ ] Не происходит обращения к Axios напрямую — только через client.
- [ ] Нет дублирования логики и неиспользуемого кода.