Nest는 데코레이터라는 언어기능을 중심을 구축되었다.
ES2016 데코레이터는 함수를 반환하고 대상, 이름 및 속성 설명자를 인수로 사용할 수 있는 표현식이다.
데코레이터 앞에 @
문자를 붙이고 이를 데코하려는 항목의 맨위에 배치하여 적용한다.
데코레이터는 클래스, 메서드, 속성에 대해 정의한다.
Nest는 HTTP route handler와 함께 사용할 수 있는 유용한 매개변수 데코레이터를 제공한다.
@Request(), @Req() | req |
---|---|
@Response(), @Res() | res |
@Next() | next |
@Session() | req.session |
@Param(param?: string) | req.params / req.params[param] |
@Body(param?: string) | req.body / req.body[param] |
@Query(param?: string) | req.query / req.query[param] |
@Headers(param?: string) | req.headers / req.headers[param] |
@Ip() | req.ip |
@HostParam() | req.hosts |
또한, Custom하게 데코레이터를 만들 수도 있다.
다음과 같이 코드를 더 읽기 쉽고 투명하게 만들기 위해 @Uesr()
데코레이터를 만들어 모든 컨트롤러에서 재사용할 수 있게 할 수 있다.
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const User = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
},
);
위 custom decorator를 다음과 같이 사용하면 된다.
@Get()
async findOne(@User() user: UserEntity) {
console.log(user);
}
데코레이터의 동작이 일부 조건에 따라 달라지는 경우 data
매개변수를 사용해 custom 데코레이터에 이를 전달할 수 있다.
이에 대한 예로 요청 객체에서 원하는 속성을 추출하는 custom 데코레이터가 있다
{
"id": 101,
"firstName": "Alan",
"lastName": "Turing",
"email": "alan@email.com",
"roles": ["admin"]
}
위와 같은 요청 객체에서 원하는 속성을 추출하는 custom 데코레이터이다.
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const User = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const user = request.user;
return data ? user?.[data] : user;
},
);
아래와 같이 위 custom 데코레이터에 엑세스해 원하는 속성을 추출한다.
@Get()
async findOne(@User('firstName') firstName: string) {
console.log(`Hello ${firstName}`);
}
Nest는 내장 매개변수 데코레이터와 동일한 방식으로 custom 매개변수 데코레이터를 처리한다.
custom 매개변수 데코레이터에 대해서도 파이프가 실핸된다.
또한 파이프를 custom 데코레이터에 직접 적용할 수 있다.
@Get()
async findOne(
@User(new ValidationPipe({ validateCustomDecorators: true }))
user: UserEntity,
) {
console.log(user);
}
위처럼 validateCustomDecorators
옵션은 true
로 설정해야 한다. 그래야 적용된다.
Nest는 여러 데코레이터를 구성하는 헬퍼 메서드를 제공한다.
예를 들어 인증관 관련된 모든 데코레이터를 단일 데코레이터로 결합해본다고 하자. 다음과 같다.
import { applyDecorators } from '@nestjs/common';
export function Auth(...roles: Role[]) {
return applyDecorators(
SetMetadata('roles', roles),
UseGuards(AuthGuard, RolesGuard),
ApiBearerAuth(),
ApiUnauthorizedResponse({ description: 'Unauthorized' }),
);
}
다음과 같이 위 데코레이터를 사용할 수 있다.
@Get('users')
@Auth('admin')
findAllUsers() {}
이제 위와 같이 4개의 데코레이터를 합친 데코레이터를 이용해 한번데 4개의 데코레이터를 단일 선언으로 적용할 수 있다.