Business-композиция
Business-композиция используется, когда простого GET-метода или прозрачного GET-хука недостаточно: нужно объединить несколько источников, преобразовать DTO или вычислить доменное состояние.
Когда использовать
- Нужно объединить несколько GET-запросов.
- Нужно вычислить
isAuth,canEdit,hasAccess,hasPets. - Нужно преобразовать DTO в доменную модель.
- Нужно спрятать бизнес-сценарий за доменным API.
Такая логика не пишется в infrastructure/. REST-клиент остаётся прозрачным адаптером к API.
Пример поверх одного GET-хука
// src/business/pets/hooks/use-available-pets.hook.ts
import { useGetPetList } from 'infrastructure/pet-store-api'
/**
* Доменный список доступных питомцев.
*/
export const useAvailablePets = () => {
const query = useGetPetList('available')
return {
...query,
hasPets: Boolean(query.data?.length),
}
}useGetPetList — infrastructure-хук. hasPets — бизнес-интерпретация, поэтому она появляется в business/pets.
Пример композиции нескольких GET-хуков
// src/business/pets/hooks/use-pets-dashboard.hook.ts
import { useGetPetList } from 'infrastructure/pet-store-api'
/**
* Данные dashboard по питомцам.
*/
export const usePetsDashboard = () => {
const availablePets = useGetPetList('available')
const pendingPets = useGetPetList('pending')
const soldPets = useGetPetList('sold')
return {
availablePets,
pendingPets,
soldPets,
total:
(availablePets.data?.length ?? 0) +
(pendingPets.data?.length ?? 0) +
(soldPets.data?.length ?? 0),
}
}Композиция нескольких запросов не добавляется в infrastructure/pet-store-api/hooks/, потому что это уже сценарий потребления данных.
Пример auth-состояния
// src/business/auth/hooks/use-auth-state.hook.ts
import { useGetCurrentUser } from 'infrastructure/backend-api'
/**
* Состояние авторизации текущего пользователя.
*/
export const useAuthState = () => {
const currentUser = useGetCurrentUser()
const user = currentUser.data
return {
...currentUser,
user,
isAuth: Boolean(user),
}
}isAuth не является частью REST-клиента. Это доменный смысл результата запроса.
Где размещать
src/business/
└── pets/
├── hooks/
│ └── use-available-pets.hook.ts
├── mappers/
│ └── map-pet-dto-to-pet.ts
├── types/
└── index.tsМодуль business/ экспортирует наружу готовый доменный API через index.ts.
Что запрещено
// Плохо — business-смысл внутри infrastructure-хука
export const useGetPetList = (status: PetStatus) => {
const query = useSWR(...)
return {
...query,
hasPets: Boolean(query.data?.length),
}
}REST-модуль отвечает за доступ к API. Business-модуль отвечает за смысл этих данных в продукте.