115 lines
3.8 KiB
Markdown
115 lines
3.8 KiB
Markdown
# Entities Layer
|
|
|
|
**Entities**는 프로젝트가 다루는 실제 비즈니스 개념을 나타내는 레이어입니다. 비즈니스에서 제품을 설명할 때 사용하는 용어들(예: User, Product, Order)이 주로 엔티티가 됩니다.
|
|
|
|
## 목적
|
|
|
|
- 비즈니스 엔티티의 데이터 모델 및 타입 정의
|
|
- 엔티티 관련 API 요청 함수 관리
|
|
- 엔티티의 시각적 표현 제공 (재사용 가능한 UI)
|
|
- 여러 페이지에서 동일한 외관을 재사용할 수 있도록 지원
|
|
|
|
## 구조
|
|
|
|
각 엔티티 슬라이스는 다음 세그먼트로 구성됩니다:
|
|
|
|
```
|
|
entities/
|
|
└── [entity-name]/
|
|
├── model/ # 데이터 저장소, 검증 스키마, 상태 관리
|
|
├── api/ # 엔티티 관련 API 요청 함수
|
|
├── ui/ # 엔티티 시각적 표현 (선택적)
|
|
├── lib/ # 엔티티 관련 유틸리티 (선택적)
|
|
├── @x/ # 다른 엔티티로부터의 cross-import용 Public API (선택적)
|
|
└── index.ts # Public API
|
|
```
|
|
|
|
### 세그먼트 설명
|
|
|
|
- **model**: 데이터 모델, 타입 정의, 상태 저장소 (Zustand 등)
|
|
- **api**: 백엔드 API 호출 함수
|
|
- **ui**: 엔티티를 표시하는 UI 컴포넌트 (완전한 UI 블록이 아니라 재사용 가능한 표현)
|
|
- **lib**: 엔티티 관련 유틸리티 함수
|
|
- **@x**: 다른 엔티티가 이 엔티티를 import할 때 사용하는 명시적 cross-import API
|
|
- **index.ts**: 슬라이스의 Public API (외부에서 사용할 수 있는 것만 export)
|
|
|
|
## 예시
|
|
|
|
```typescript
|
|
// entities/user/model/user.ts
|
|
export interface User {
|
|
id: string;
|
|
name: string;
|
|
email: string;
|
|
role: 'admin' | 'user';
|
|
}
|
|
|
|
// entities/user/api/get-user.ts
|
|
import type { User } from '../model/user';
|
|
|
|
export async function getUser(id: string): Promise<User> {
|
|
const response = await fetch(`/api/users/${id}`);
|
|
return response.json();
|
|
}
|
|
|
|
// entities/user/ui/user-card.tsx
|
|
import type { User } from '../model/user';
|
|
|
|
interface UserCardProps {
|
|
user: User;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export function UserCard({ user, onClick }: UserCardProps) {
|
|
return (
|
|
<div onClick={onClick}>
|
|
<h3>{user.name}</h3>
|
|
<p>{user.email}</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// entities/user/index.ts
|
|
export { type User } from './model/user';
|
|
export { getUser } from './api/get-user';
|
|
export { UserCard } from './ui/user-card';
|
|
```
|
|
|
|
## 엔티티 간 관계
|
|
|
|
엔티티가 서로 연결되어 있을 때는 `@x` 표기법을 사용하여 명시적으로 cross-import를 관리하는 것이 권장됩니다:
|
|
|
|
```typescript
|
|
// entities/artist/model/artist.ts
|
|
import type { Song } from 'entities/song/@x/artist';
|
|
|
|
export interface Artist {
|
|
name: string;
|
|
songs: Array<Song>;
|
|
}
|
|
|
|
// entities/song/@x/artist.ts
|
|
export type { Song } from '../model/song';
|
|
```
|
|
|
|
> `@x` 폴더를 사용하면 엔티티 간 연결을 명확하게 만들어 함께 리팩터링이 필요한 코드를 쉽게 찾을 수 있습니다.
|
|
|
|
## 레이어 의존성 규칙
|
|
|
|
✅ **허용되는 의존성**:
|
|
- `shared` 레이어의 모듈
|
|
- 같은 엔티티 슬라이스 내의 다른 세그먼트
|
|
- 다른 엔티티 슬라이스 (필요한 경우, `@x` 표기법 권장)
|
|
|
|
❌ **금지된 의존성**:
|
|
- `features` 레이어
|
|
- `widgets` 레이어
|
|
- `pages` 레이어
|
|
- `app` 레이어
|
|
|
|
## 주의사항
|
|
|
|
1. **UI 컴포넌트는 완전한 비즈니스 로직을 포함하지 않음**: UI는 주로 props나 slots를 통해 다양한 비즈니스 로직을 연결할 수 있도록 설계
|
|
2. **엔티티 간 비즈니스 로직은 상위 레이어에**: 엔티티 간 상호작용의 비즈니스 로직은 Features나 Pages 레이어에서 처리
|
|
3. **데이터 관리에 집중**: 복잡한 비즈니스 로직보다는 데이터 모델, 검증, 저장에 집중
|