콘텐츠로 이동

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 토큰 스트리밍처럼 긴 응답이 필요한 경우 컨트롤러에서 응답을 직접 다루는 방식을 선택적으로 사용합니다.

더 알아보기