데코레이터를 이해하기 위해서는 먼저 "데코레이션(decoration)"이라는 단어의 의미부터 생각해보면 좋다. 데코레이션은 장식이나 꾸밈을 의미하는데, 프로그래밍에서의 데코레이터도 이와 비슷한 역할을 한다.
즉, 기존의 코드에 추가적인 기능이나 정보를 "장식"하는 것이다.
데코레이터는 TypeScript의 기능으로, 클래스, 메서드, 속성, 매개변수 등에 적용할 수 있는 특별한 종류의 선언이다.
이를 통해 우리는 해당 요소에 추가적인 기능을 부여하거나, NestJS 프레임워크에게 어떻게 해당 요소를 처리해야 하는지 알려줄 수 있다.
NestJS는 내부적으로 많은 데코레이터를 제공한다.
예를 들어, HTTP 요청을 처리하는 컨트롤러를 만들 때, @Controller() 데코레이터를 사용하여 해당 클래스가 컨트롤러임을 NestJS에 알려준다.
마찬가지로, @Get(), @Post() 같은 데코레이터를 사용하여 특정 HTTP 메서드를 처리하는 함수임을 표시한다.
자주 사용하는 SNS 앱에 새로운 글을 게시하는 기능이 있다고 가정해 보자. NestJS에서 이 기능을 구현할 때, @Post() 데코레이터를 사용하여 사용자가 글을 게시할 때마다 이 함수가 실행되어야 함을 알린다.
@Controller('posts')
class PostsController {
@Post()
createPost() {
// 여기에 글을 게시하는 코드를 작성.
}
}
이 예시에서 @Controller('posts') 데코레이터는 PostsController 클래스가 posts 경로에 대한 요청을 처리하는 컨트롤러임을 알려준다.
그리고 @Post() 데코레이터는 createPost 메서드가 POST 요청을 처리해야 함을 의미한다.
NestJS에서 데코레이터는 마법처럼 보일 수 있지만, 사실은 클래스나 메서드에 추가 기능이나 메타데이터를 "장식"하여 NestJS 프레임워크가 해당 코드를 어떻게 처리할지 알 수 있게 해주는 강력한 도구다. 이를 통해 우리는 더 깔끔하고 체계적인 방식으로 코드를 구성할 수 있다.
컨트롤러는 매일 사용하는 스마트폰 앱을 생각해보면 이해하기 쉽다. 예를 들어, Instagram이나 Facebook과 같은 앱에 사진을 올리거나, 친구의 새 소식을 확인할 때, 앱의 서버에 여러 요청을 하게 된다.
이때, 서버에서는 그 요청을 받아서 무엇을 해야 할지 결정해야 하는데, 이런 역할을 하는 것이 바로 컨트롤러다.
컨트롤러는 사용자의 요청을 받아서 처리하는 부분이다.
간단히 말해서, 사용자가 앱에서 어떤 동작(예: 게시물 보기, 사진 업로드)을 할 때, 그 요청을 받아서 그에 맞는 데이터를 가져오거나 데이터베이스에 정보를 저장하는 등의 역할을 한다.
NestJS에서 컨트롤러는 특정 경로(route)에 대한 요청을 처리하는 클래스다.
각 컨트롤러는 하나 이상의 경로를 가질 수 있으며, 경로는 일반적으로 웹 URL과 연결된다.
요청 받기:
사용자 또는 클라이언트로부터 오는 요청을 받는다.
비즈니스 로직 실행:
사용자의 요청에 따라 필요한 작업을 실행한다. 이는 데이터를 조회하거나, 수정, 삭제하는 등의 작업일 수 있다.
응답 반환:
작업의 결과를 사용자에게 반환한다.
이 때, 응답은 HTML 페이지일 수도 있고, JSON 데이터일 수도 있다.
NestJS에서 컨트롤러를 만들 때는 클래스에 @Controller() 데코레이터를 사용한다.
그리고 각 메서드에 @Get(), @Post(), @Put(), @Delete()와 같은 데코레이터를 사용하여 해당 메서드가 처리할 HTTP 메서드와 경로를 지정한다.
@Controller('users')
class UsersController {
@Get()
findAll() {
// 모든 사용자를 조회하는 로직
}
@Post()
create() {
// 새 사용자를 생성하는 로직
}
}
이 예시에서 @Controller('users')는 UsersController 클래스가 users 경로에 대한 요청을 처리하는 컨트롤러임을 나타낸다.
@Get() 데코레이터가 붙은 findAll 메서드는 GET 요청을 처리하며, 사용자가 /users 경로에 GET 요청을 보낼 때 호출된다.
마찬가지로, @Post() 데코레이터가 붙은 create 메서드는 POST 요청을 처리한다.
컨트롤러는 사용자의 요청을 직접 받아 처리하는 NestJS 애플리케이션의 핵심 부분이다.
각 요청에 따라 적절한 비즈니스 로직을 실행하고 결과를 반환하는 역할을 한다.
이를 통해 개발자는 애플리케이션의 다양한 기능을 구조적이고 효율적으로 구현할 수 있다.
모듈은 NestJS에서 애플리케이션의 구조를 구성하는 기본적인 빌딩 블록이다.
이해하기 쉬운 비유로 설명하자면, 모듈은 학교에서 각각의 반과 같다.
학교에는 여러 반들이 있고, 각 반은 서로 다른 학생들(컨트롤러와 서비스)과 교과목(기능)을 가지고 있다.
학교 전체를 효율적으로 관리하기 위해, 관련된 학생들과 교과목들을 하나의 반으로 그룹화한다.
마찬가지로, NestJS에서도 관련된 기능들을 모아 하나의 모듈로 구성하여 애플리케이션을 효율적으로 관리하고 구조화한다.
모듈은 다음과 같은 역할을 한다:
애플리케이션의 기능을 관련된 부분끼리 그룹화하여 구조화한다.
이를 통해 코드의 유지 관리와 확장이 용이해진다.
모듈은 애플리케이션의 특정 부분을 캡슐화하여, 모듈 내부의 구현 세부사항을 외부로부터 숨긴다.
이를 통해 내부 구현의 변경이 모듈을 사용하는 다른 부분에 영향을 주지 않도록 한다.
공통 기능을 모듈로 분리함으로써, 다른 애플리케이션 부분에서 해당 모듈을 재사용할 수 있다.
NestJS에서 모듈은 @Module() 데코레이터를 사용하여 정의된다.
이 데코레이터는 해당 모듈에 포함될 컨트롤러, 서비스(프로바이더), 그리고 다른 모듈들을 메타데이터 형태로 제공받는다.
@Module({
controllers: [PostsController],
providers: [PostsService],
imports: [DatabaseModule],
})
export class PostsModule {}
이 예시에서 PostsModule은 게시글과 관련된 기능을 담당하는 모듈이다.
controllers 배열에는 이 모듈이 처리할 요청을 담당하는 컨트롤러가 포함되어 있고, providers 배열에는 데이터 처리와 비즈니스 로직을 담당하는 서비스가 포함된다.
또한, imports 배열을 통해 다른 모듈(예: 데이터베이스 연결을 관리하는 DatabaseModule)을 포함시킬 수 있다.
모듈은 NestJS 애플리케이션을 구조적이고 효율적으로 구성하는 데 도움을 주는 핵심적인 요소이다.
각 모듈은 애플리케이션의 특정 기능 부분을 책임지며, 모듈을 통해 애플리케이션의 다양한 기능들이 서로 잘 연결되고 조화롭게 작동하도록 한다.
이를 통해 애플리케이션의 유지 관리와 확장성을 크게 향상시킬 수 있다.