Controller
- 컨트롤러는
NestJS애플리케이션의 핵심 구성 요소 중 하나로, 클라이언트의 HTTP 요청을 받고 응답을 반환하는 역할을 담당한다. 즉, 특정 URL 경로(Endpoint)에 대한 로직을 정의하는 곳이다.
컨트롤러 생성과 라우팅 (Routing)
@Controller()데코레이터 : 클래스 선언 위에@Controller()데코레이터를 붙여 해당 클래스가 컨트롤러임을 나타낸다.
import { Controller, Get } from '@nestjs/common';
@Controller('cats') // '/cats' 경로로 들어 오는 요청을 본 컨트롤러가 처리
export class CatsController {
@Get() // GET /cats 요청을 본 메서드가 처리
findAll(): string {
return 'This action returns all cats';
}
@Get('special') // GET /cats/special 요청을 본 메서드가 처리
findSpecial(): string {
return 'This is a special Cat';
}
}- 경로 접두사 (Prefix) :
@Controller('cats')와 같이 인자를 주면 해당 컨트롤러 내부의 모든 라우팅 경로 앞에/cats가 공통으로 붙어, 이를 통해 관련 API 를 그룹화 할 수 있다. - HTTP 요청 메서드 데코레이터 :
@Get(),@Post(),@Put(),@Delete(),@Patch(),@Options(),@Head()등 다양한 HTTP 메서드에 맞는 데코레이터를 사용하여 요청을 처리할 메서드(핸들러)를 지정한다.
서브 도메인 라우팅
NestJS에서 서브 도메인 기반으로 라우팅을 처리하는 방법으로, HTTP 요청의 도메인에 따라 다른 컨트롤러가 요청을 처리하도록 설계하는 기능이다.@Controller()데코레이터에서host옵션을 사용하여, 특정 HTTP 호스트(도메인)에서 들어오는 요청만 해당 컨트롤러가 처리하도록 제안할 수 있다.- 관리자 페이지와 같은 특정 서브 도메인에서만 접근해야 하는 기능을 구현할 때 유용하다.
@Controller({ host: 'admin.example.com' }) // 본 컨트롤러는 'admin.example.com'으로 들어오는 요청만 처리한다.
export class AdminController {
@Get() // GET admin.example.com/ 오청을 처리한다.
index(): string {
return 'Admin Page'
}
}NestJS의 기본 설정인Express어댑터 이외의Fastify는 서브도메인 라우팅과 같은 중첩된 라우팅을 지원하지 않기 때문에, 복잡한 라우팅 구조를 사용할 때는Express를 사용해야 한다.
@HostParam()
@Controller({ host: ':account.example.com' }) // 본 컨트롤러는 'admin.example.com'으로 들어오는 요청만 처리한다.
export class AccountController {
@Get() // GET admin.example.com/ 오청을 처리한다.
index(@HostParam('account') account: string): string {
return account
}
}Request 처리
클라이언트가 보낸 데이터를 가져오기 위해 다양한 데코레이터를 사용한다.
@Param(key): 경로의 일부를 동적인 값으로 받을때 사용- 경로 :
@Get(':id') - URL 예시 :
/cats/123 findOne(@Param('id') id: string): id 변수에 '123'이 담긴다.
- 경로 :
@Query(key): URL의 쿼리 스트링 값을 가져올때 사용- URL 예시 :
/cats?name=goyangee&age=2 find(@Query('name') name: string): name 변수에 'goyangee'가 담긴다.
- URL 예시 :
@Body():POST나PUT요청 시 본문(body)에 담겨 오는 데이터를 객체로 받아 올때 사용- 요청 Body (JSON) :
{ "name": "goyangee", "age": 2, "species": "horangee" } create(@Body() createCatDto: CreateCatDto): createCatDto 객체에 JSON 데이터가 매핑된다.
- 요청 Body (JSON) :
DTO (Data Transfer Object) :
@Body()로 데이터를 받을 때, Class를 사용하여 데이터의 형태를 정의하는 것이 좋다. 이를 DTO라고 부르며, 타입 안정성을 높이고 코드의 가독성을 향상 시킨다.@Req(),@Request():Express나Fastify의 원시 요청(request) 객체에 직접 접근해야 할 때 사용하지만 일반적으로@Param,@Body등의 데코레이터를 사용하는 것이 권장된다.
Reponse 처리
NestJS는 응답을 처리 하기 위해표준 방식(Standard),라이브러리 지정 방식(Library-specific)두 가지 방식을 제공한다.표준 방식 (Standard)
- 권장되는 방식으로, 핸들러 메서드에서 JS 객체나 배열, 원시 타입 값을 return 하면
NestJS가 자동으로 JSON으로 변환하고 적절한 HTTP 상태 코드와 함께 응답한다. @HttpCode(code): 기본 상태 코드를 다른 것으로 변경하고 싶을 때 사용한다.@Header(key, value): 응답 헤더를 설정할 때 사용한다.
- 권장되는 방식으로, 핸들러 메서드에서 JS 객체나 배열, 원시 타입 값을 return 하면
라이브러리 지정 방식 (Library-specific)
@Res()데코레이터를 사용하여 응답 객체에 직접 접근한다.res.status(200).json(...)과 같이 Express의 네이티브 응답 메서드를 호출하여 수동으로 응답을 제어한다.- 해당 방식을 사용하면
NestJS의 표준 응답 처리 기능이 비활성화 된다.
Running
NestJS는 모듈 기반의 아키텍처를 가지고 있어, 모든 애플리케이션 구성 요소(Controller,Service,Provider등)는 반드시 특정 모듈(Module)에 속해야 한다.NestJS는 이 모듈들을 통해 애플리케이션의 구조를 파악하고, 필요한 인스턴스를 생성하며, 의존성 주입을 관리한다.
// app.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
@Module({
controllers: [CatsController],
})
export class AppModule {}@Module데코레이터는 모듈 클래스에 메타데이터를 첨부하는 역할로,NestJS는 이 메타데이터를 읽어서 어떤Controller들을 마운트 해야 하는지 파악한다.