개발스토리
Nest - Controllers 본문
Nest 공식 문서를 바탕으로 정리한 게시글입니다.
컨트롤러는 들어오는 request를 처리한 후 response를 클라이언트에 반환한다.
라우팅 메커니즘으로 어떤 컨트롤러가 어떤 request를 수신하는 지 제어한다. 컨트롤러에 둘 이상의 라우트가 있을 수 있고 다른 작업을 수행할 수 있다.
기본 컨트롤러를 만들기 위해서는 클래스와 데코레이터를 사용한다. 데코레이터는 클래스를 필수 메타데이터와 연결한 후 Nest가 라우팅 맵을 만들 수 있도록 한다.
Routing
코드를 통해 이해해보자.
// cats.controller.ts
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
우선, 기본 컨트롤러를 정의하는 데 필수인 @Controller() 데코레이터를 사용한다. 이 데코레이터에 있는 접두사 cats는 라우팅을 사용하는 자원의 경로가 된다. 관련 라우트 집합을 그룹화하고 반복 코드를 줄여준다. @Controller() 데코레이터에 포함되어 있는 라우트들의 사용 경로가 /cats로 시작 된다는 뜻이다.
@Get() HTTP 요청에 대해서는 findAll()이 수행된다. 현재 코드에서 findAll메서드를 사용하기 위해서는 GET /cats 요청을 보내야한다. @Get('/find')로 되어 있을 경우에는 GET /cats/find 요청을 보내야 한다.
Request object
// cats.controller.ts
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';
@Controller('cats')
export class CatsController {
@Get()
findAll(@Req() request: Request): string {
return 'This action returns all cats';
}
}
핸들러는 종종 클라이언트의 요청 세부정보에 액세스해야 한다. Nest는 기본 플랫폼(default는 express)의 요청 객체에 대한 액세스를 제공한다. @Req() 데코레이터를 추가하여 Nest에 주입하면 된다.
* 요청 객체는 HTTP 요청이며 쿼리 문자열, 매개변수, HTTP 헤더 및 본문 등을 포함한다. 바로 사용할 수 있는 전용 데코레이터들이 존재한다.
Resources
import { Controller, Get, Post } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Post()
create(): string {
return 'This action adds a new cat';
}
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
위 코드에서는 GET /cats만 정의했었다. 이번에는 POST 핸들러가 포함되었다. 이런식으로 간단하게 엔드포인트를 정의해줄 수 있다.
Nest는 모든 표준 HTTP 메서드에 대한 데코레이터를 제공한다.
Status code
@Post()
@HttpCode(204)
create() {
return 'This action adds a new cat';
}
응답 상태코드는 201이 포함된 POST 요청을 제외하고 기본적으로 항상 200이다. @HttpCode() 데코레이터를 통해 동작을 변경할 수 있다. @nestjs/common 패키지에서 가져오면 된다.
Route parameters
@Get(':id')
findOne(@Param() params): string {
console.log(params.id);
return `This action returns a #${params.id} cat`;
}
요청의 일부로 동적 데이터를 수락해야 하는 경우 매개변수가 있는 라우트를 정의해야 한다. 요청 URL의 해당 위치에서 토큰을 추가한다. @Param() 데코레이터를 사용하여 액세스 한다. 현재 코드에서는 params.id를 참조해서 id를 액세스 한다. 하지만 특정 매개변수 토큰을 데코레이터에 전달하면 이름으로 바로 사용 가능하다.
@Get(':id')
findOne(@Param('id') id: string): string {
return `This action returns a #${id} cat`;
}
Sub-Domain Routing
@Controller 데코레이터는 들어오는 요청의 HTTP 호스트가 특정값과 일치하도록 host 옵션을 사용할 수 있다.
@Controller({ host: 'admin.example.com' })
export class AdminController {
@Get()
index(): string {
return 'Admin page';
}
}
host 옵션은 토큰을 사용하여 호스트 이름의 해당 위치에서의 동적값을 캡처할 수 있다. 선언된 호스트 매개변수는 @HostParam() 데코레이터를 사용하여 액세스할 수 있다.
@Controller({ host: ':account.example.com' })
export class AccountController {
@Get()
getInfo(@HostParam('account') account: string) {
return account;
}
}
Request payloads
// create-cat.dto.ts
export class CreateCatDto {
name: string;
age: number;
breed: string;
}
// cats.controller.ts
@Post()
async create(@Body() createCatDto: CreateCatDto) {
return 'This action adds a new cat';
}
@Body() 데코레이터를 추가해서 POST 라우트 핸들러의 클라이언트 매개변수를 허용해보자.
TypeScript를 사용하는 경우 DTO 스키마를 결정해야 한다. DTO는 데이터가 네트워크를 통해 전송되는 방식을 정의하는 객체이다. 인터페이스나 클래스를 사용하여 정의할 수 있는데, 클래스를 사용하는 것이 좋다. 클래스는 ES6 표준이므로 컴파일된 자바스크립트에서 실제 엔티티로 유지되기 때문이다. 인터페이스는 트랜스 파일중에 제거되기 때문에 Nest는 런타임에 이를 참조할 수 없다.
Getting up and running
// app.module.ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
@Module({
controllers: [CatsController],
})
export class AppModule {}
컨트롤러가 완전히 정의가 되어도 Nest는 컨트롤러가 존재하는 지 알지 못한다. 컨트롤러는 항상 모듈에 속하므로 위의 코드처럼 @Module() 데코레이너 내에 컨트롤러를 포함시켜줘야 한다. ( AppModule을 제외한 모듈은 정의한 적 없으므로 위 코드처럼 작성한다. cats.module.ts가 있다면 여기에 컨트롤러를 포함시키고 모듈 자체를 AppModuel에 넣어주면 된다 )
'Nestjs' 카테고리의 다른 글
Nest - Exception filters (0) | 2021.07.19 |
---|---|
Nest - Hot Reload with CLI (0) | 2021.06.28 |
Nest - First steps (1) | 2021.06.25 |
Nest - Introduction (0) | 2021.06.25 |