NestJS 애플리케이션에 HTTP 요청이 들어오면 가장 먼저 Controller가 이를 받는다. Controller는 요청의 경로(Route)와 메서드(GET, POST 등)를 보고 어떤 로직을 실행할지 결정하며, 실제 비즈니스 로직은 Service에 위임한다. 이 분리 덕분에 코드의 역할이 명확해지고 테스트가 쉬워진다.
Client
│
▼
[ HTTP Request ]
│
▼
Controller ──→ Service ──→ Repository
│ │
◄──────────────────────────────
│
▼
[ HTTP Response ]
Client의 요청은 Controller에서 수신되고, Controller는 Service를 호출해 결과를 받아 응답으로 반환한다. Controller가 직접 DB를 건드리지 않는 것이 핵심이다.
@Controller 데코레이터를 클래스에 붙이면 NestJS가 해당 클래스를 Controller로 인식한다. 인자로 Route prefix를 지정할 수 있다.
import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(@Query('role') role?: string) {
return this.usersService.findAll(role);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.usersService.create(createUserDto);
}
}
Route prefix: @Controller('users')로 지정하면 이 Controller의 모든 Route는 /users로 시작한다.
| 데코레이터 | HTTP 메서드 | 용도 |
|---|---|---|
@Get | GET | 리소스 조회 |
@Post | POST | 리소스 생성 |
@Put | PUT | 리소스 전체 수정 |
@Patch | PATCH | 리소스 부분 수정 |
@Delete | DELETE | 리소스 삭제 |
각 데코레이터에 경로를 추가하면 prefix에 이어 붙는다. @Controller('users')와 @Get(':id')의 조합은 GET /users/:id가 된다.
클라이언트가 보내는 데이터는 세 가지 위치에 담길 수 있고, 각각 대응하는 데코레이터가 있다.
@Get(':id')
findOne(
@Param('id') id: string, // URL 경로 변수: /users/42
@Query('sort') sort: string, // 쿼리스트링: /users?sort=asc
) { ... }
@Post()
create(
@Body() dto: CreateUserDto, // 요청 본문(JSON)
) { ... }
@Param: URL 경로의 :id 같은 동적 세그먼트를 추출한다. @Query: ?key=value 형태의 쿼리스트링을 추출한다. @Body: Content-Type: application/json 요청의 본문을 추출한다.
Controller는 반드시 해당 Module의 controllers 배열에 등록해야 NestJS IoC 컨테이너가 인식한다.
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
Controller를 등록하지 않으면 라우트가 동작하지 않고, 요청 시 404가 반환된다. providers에 Service를 함께 등록해야 Controller의 생성자 주입이 정상 동작한다.