| 계층 | 책임 | 금지 사항 |
|---|---|---|
| Controller | HTTP 요청/응답, Validation Pipe 연결 | 비즈니스 로직 작성 |
| Service | 비즈니스 로직, 외부 API/DB 접근 | Request/Response 객체 접근 |
| Entity | DB 스키마 표현 | 비즈니스 로직 (최소화) |
| DTO | 외부와 주고받는 데이터 정의 | - |
| Module | 의존성 조합 | - |
| Guard / Interceptor | 횡단 관심사 (인증, 로깅 등) | - |
Controller → Service → Repository → Entity
↓ ↓
DTO DTO
규칙:
src/[domain]/
├── domain.module.ts
├── domain.controller.ts
├── domain.service.ts
├── domain.repository.ts
├── dto/
│ ├── create-domain.dto.ts
│ ├── update-domain.dto.ts
│ └── get-domain-response.dto.ts
├── entities/
│ └── domain.entity.ts
└── types/
└── external-api.type.ts
[도메인].[역할].ts 형식# Good
users/
users.controller.ts
users.service.ts
# Bad
user/
user.controller.ts
// Good: Service 레벨에서 다른 Service 주입
@Injectable()
export class OrdersService {
constructor(private readonly usersService: UsersService) {}
async createOrder(userId: string) {
const user = await this.usersService.findOne(userId);
// ...
}
}
// Bad: Controller에서 다른 도메인 Service 직접 사용
@Controller('orders')
export class OrdersController {
constructor(
private readonly ordersService: OrdersService,
private readonly usersService: UsersService, // ❌
) {}
}
규칙: