Nest3 - 기본 프로젝트 구조
NestJs 프로젝트 구조
NestJS 프로젝트는 기본적으로 Module, Controller, Service로 구성되어 있다.
Module은 애플리케이션의 기능을 조직화하고 의존성을 관리하는데 사용되는 중요한 구성 요소이며 컨트롤러, 서비스, 미들웨어 등의 관련된 기능을 하나로 묶어 관리하는 역할을 한다. Controller, Service는 기존 MVC 패턴 구조와 동일하게 사용된다.
NestCLI를 활용한 기본 프로젝트 구조 생성
NestCLI를 활용하면 친절하게 도메인별로 기본 프로젝트 구조를 생성할 수 있다.
프로젝트 경로에서 아래 명령어를 실행하면 된다. 예시로 member 도메인 관련 파일들을 생성해보자.
1
nest g resource member
위와 같이 src/member 디렉토리에 관련된 프로젝트 파일이 생성된 것을 확인할 수 있다.
기본적으로 controller, service, module 파일이 생성되고, spec은 테스트 관련 파일이다.
NestCLI를 활용하면 간단하게 프로젝트 구조를 생성해주기 때문에 개발자는 비즈니스 로직에 집중할 수 있다.
Controller
member.ontroller.ts
파일을 확인해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Controller('member')
export class MemberController {
constructor(private readonly memberService: MemberService) {}
@Post()
create(@Body() createMemberDto: CreateMemberDto) {
return this.memberService.create(createMemberDto);
}
@Get()
findAll() {
return this.memberService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.memberService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateMemberDto: UpdateMemberDto) {
return this.memberService.update(+id, updateMemberDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.memberService.remove(+id);
}
}
위와 같이 기본 RestAPI 방식의 CRUD 메서드가 생성된 것을 확인할 수 있다.
클래스 위에 붙어있는 @Controller는 해당 클래스가 컨트롤러임을 나타내는 decorator로, 반드시 붙여줘야만 모듈을 통해 의존성이 부여된다.
1
2
3
4
@Get()
findOneById(@Query('id') id: string) {
return this.memberService.findOne(+id);
}
위 메서드도 참고하자. url 상 query로 들어오는 데이터의 경우 @Query
데코레이터를 활용하면 매핑되어 받아올 수 있다.
Service
member.service.ts
파일도 확인해보자.
아래와 같이 Service 클래스에 간단한 비즈니스 로직 메소드들이 생성된 것을 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Injectable()
export class MemberService {
create(createMemberDto: CreateMemberDto) {
return 'This action adds a new member';
}
findAll() {
return `This action returns all member`;
}
findOne(id: number) {
return `This action returns a #${id} member`;
}
update(id: number, updateMemberDto: UpdateMemberDto) {
return `This action updates a #${id} member`;
}
remove(id: number) {
return `This action removes a #${id} member`;
}
}
중요한 것은 Service 클래스도 Controller와 동일하게 의존성 주입이 가능하도록 데코레이터가 필요하다. @Injectable()
데코레이터가 그 역할을 한다.
Module
member.module.ts 파일을 확인해보자.
1
2
3
4
5
@Module({
controllers: [MemberController],
providers: [MemberService],
})
export class MemberModule {}
위와 같이 NestCLI를 활용하여 파일 생성 시, Module 클래스에 Controller와 Service 클래스가 자동으로 등록된다.
controllers: []
에는 Member 모듈에서 사용되는 Controller 클래스를 등록한다.
providers: []
에는 Member 모듈에서 사용되는 의존성 주입 가능한 클래스를 등록한다.
즉, providers는 @Injectable
데코레이터가 붙어있는 클래스들을 등록해주면 되는 것이다.
정리
Member라는 도메인을 모듈로 구성한 하나의 모듈 구조라고 생각하면 이해하기 쉽다.
하나의 프로젝트에 이러한 모듈 구조는 여러개 생성할 수 있으며 NestCLI를 활용하면 쉽게 생성할 수 있다. 그러나 Member 모듈은 내부에서만 동작하기 때문에 다른 모듈과 상호작용 및 의존성 주입을 받을 수 없다. 따라서 모듈을 한 곳에서 관리하고 모듈간 의존성을 주입하여 사용할 수 있도록 모듈을 관리하는 곳이 필요한데, 그 곳이 AppModule 클래스이다.
NestCLI로 모듈 생성 시에는 자동으로 AppModule에 생성된 모듈이 등록된다.
1
2
3
4
5
6
@Module({
imports: [MemberModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
위와 같이 MemberModule이 import 되어 있는 것을 확인할 수 있다.
imports: []
에 모듈을 등록해주면 해당 모듈에서 제공하는 서비스 및 컴포넌트를 다른 모듈에서 사용할 수 있게 된다.