NestJS 컨트롤러와 라우팅¶
개요¶
HTTP 요청이 가장 먼저 닿는 곳이 컨트롤러(controller)예요. 컨트롤러는 들어온 요청을 받아서, 필요한 데이터를 꺼내고, 그 일을 처리할 서비스를 부른 뒤 응답을 돌려주는 역할을 합니다. NestJS에서 컨트롤러는 @Controller() 데코레이터를 단 클래스이고, 각 메서드에 HTTP 메서드 데코레이터를 붙여 어떤 요청을 처리할지 정합니다. 빠르게 CRUD 컨트롤러가 필요하면 CLI의 CRUD 생성기(nest g resource [name])를 쓰면 검증까지 포함해 만들어 줘요.
핵심 개념¶
경로는 컨트롤러 접두사 + 메서드 경로의 합¶
라우트 경로는 컨트롤러에 선언한 (선택적) 접두사와 메서드 데코레이터의 경로를 합쳐서 결정됩니다.
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
여기서는 접두사 cats만 있고 메서드에 추가 경로가 없으니 GET /cats가 이 핸들러로 매핑돼요. 만약 메서드에 @Get('breed')를 붙이면 결과는 GET /cats/breed가 됩니다.
HTTP 메서드 데코레이터¶
표준 HTTP 메서드에 대응하는 데코레이터가 모두 있어요. @Get(), @Post(), @Put(), @Delete(), @Patch(), @Options(), @Head()가 있고, @Query() 파라미터 데코레이터와 이름이 겹치지 않도록 QUERY 메서드를 담당하는 @QueryMethod()도 있습니다.
요청 객체 접근¶
@Req()로 요청 객체를 직접 받을 수도 있어요. 다만 @Res()나 @Response()를 주입하면 해당 핸들러는 라이브러리 전용 모드가 되어, Nest가 응답을 관리하지 않고 개발자가 직접 응답을 처리하게 됩니다. 기본 라우팅 중심 방식에서는 @Res() 사용을 자제하는 게 권장돼요.
요청 파라미터 데코레이터¶
경로 파라미터는 @Param(), 쿼리는 @Query(), 본문은 @Body()로 받습니다. 이렇게 꺼낸 값을 컨트롤러 밖으로 넘겨주면 서비스 로직까지 깔끔하게 이어져요.
서브 도메인 라우팅¶
@Controller 데코레이터는 host 옵션을 받아 호스트 이름으로도 라우팅을 걸 수 있어요. 예를 들어 @Controller({ host: 'admin.example.com' })처럼 쓰면 특정 도메인으로 온 요청만 처리합니다. 다만 Fastify는 중첩 라우터를 지원하지 않으므로, 서브 도메인 라우팅을 쓸 때는 기본 Express 어댑터를 권장해요.
모듈에 등록¶
컨트롤러는 항상 모듈의 일부여야 해요. 루트 AppModule의 @Module()에 controllers 배열로 등록하면 사용할 수 있습니다.
실제 적용 (데이터스케쳐스 관점)¶
웹빌더 백엔드에서 컨트롤러는 API 진입점을 정리하는 역할을 해요.
- 라우트 정리 — RESTful 엔드포인트를 컨트롤러 단위로 묶고, 접두사로 리소스 경계를 명확히 해요.
- DTO 바인딩 —
@Body()로 요청 본문을 DTO에 담아 검증 파이프로 보내고, 잘못된 입력이 서비스까지 내려가지 않게 해요. - SSE 스트리밍 — LLM 토큰 스트리밍처럼 긴 응답이 필요한 경우 컨트롤러에서 응답을 직접 다루는 방식을 선택적으로 사용합니다.
더 알아보기¶
- 공식 문서 (1차): NestJS Controllers
- 인접 챕터: 모듈과 의존성 주입 · Providers와 DI
- 상위 문서: NestJS (v10·v11)