오늘은 NestJS에서 데코레이터중 하나를 포스팅 해보려고 한다.
Api개발을 할때 Controller에서 User정보를 토큰 값으로 받아서 개발을 할때 @CurrentUser 라는 데코레이터를 많이들 사용할 것이다.
- controller부
이처럼 @CurrentUser() user 를 사용하게 되면 "user" 에 토큰으로받은 유저정보가 담기게 될것이다.
console.log(user)를 해보면 user정보가 잘 넘어온다는 것을 확인해 볼 수 있을 것이다.
하지만 이럴경우 Service부로 넘어가는 파라미터가 두개가 되고 user관련 데이터 정제를 하게될 시 코드가 길어진다는 단점이 있다.
그래서 이런단점을 커버해주기 위해서 요새는 @CurrentUser 대신 다른 데코레이터를 사용한다.
@UseInterceptors(InjectUserInfoInterceptor)
우선 관련 코드를 먼저 살펴보자
- controller부
- userinfo.interceptor.ts
코드를 보면 @CurrentUser 대신
@UseInterceptors(InjectUserInfoInterceptor) 데코레이터가 보일 것이다.
쉽게 말해서 이 데코레이터는 @Body() 나 @Param()에 토큰의 user정보를 담아주는 역할을 한다.
코드에서 @body로 "dto: CreateFollowsDto" 를 사용하였는데
console.log(dto)를 해보면
interceptor에 넣어둔 유저정보 ( user.name , user.profile_image , user.uuid ) 와 CreateFollowsDto의 정보가 나올 것이다.
service부로 넘길때도 깔끔히 dto만 넘길 수 있고 훨씬 더 깔끔해진 코드를 볼 수 있을 것이다.
해당 Interceptor에 코드는 다음과 같다.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class InjectUserInfoInterceptor implements NestInterceptor {
private readonly logger = new Logger(InjectUserInfoInterceptor.name);
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const http = context.switchToHttp();
const request = http.getRequest();
const { query, body, user } = request;
if (body) {
body.user_name = user.name;
body.profile_image = user.profile_image;
body.user_uuid = user.uuid;
this.logger.debug(JSON.stringify(body));
}
if (query) {
query.user_name = user.name;
query.profile_image = user.profile_image;
query.user_uuid = user.uuid;
this.logger.debug(JSON.stringify(query));
}
return next.handle().pipe();
}
}