본문 바로가기
Back-end/기초부터 따라하는 nest.js

#13. 기초부터 따라하는 Nest.js : Interceptor

by hsloth 2023. 5. 17.

 

해당 포스팅은 nest.js 9.0.0 버전, typeorm 0.3.x 버전을 기준으로 작성되었습니다.
모든 글은 작성자의 주관이 100% 담겨있기 때문에 부정확할 수 있습니다.

 

#pre. 터미널을 켜고 프로젝트 폴더로 이동

https://suloth.tistory.com/44

 

#0-1. 기초부터 따라하는 nest.js : 터미널 키는 법 + 터미널에서 작업 폴더 이동

윈도우 윈도우는 윈도우+R 버튼을 누른 후, cmd 를 입력하여 터미널을 킵니다. 혹은 윈도우 버튼을 눌러서 검색창에 cmd를 검색하면 터미널이 나올텐데 그걸 실행시켜주시면 됩니다. Mac OS Mac의 경

suloth.tistory.com

 
위의 링크의 내용을 참고하여 study 폴더로 이동해줍니다.
그리고 code . 명령어를 통해 vscode를 열어줍니다.


Interceptor


인터셉터란?

말 그대로 가로채는 녀석입니다.

컨트롤러 실행 전, 후에 요청을 가로채서 특정 동작을 넣어줍니다.

특정 미들웨어가 중복될 경우(미들웨어가 뭔지 모르신다면, 검색해 보시는 걸 추천합니다) 인터셉터를 사용하여 중복을 제거할 수 있습니다.

 

제일 대표적인 인터셉터로는 undefined를 null로 변환해주는 인터셉터가 있습니다.

src폴더에 interceptors 폴더를 생성하고 undefinedToNull.interceptor.ts 파일을 만들어 봅시다.

 

 

//undefinedToNull.Interceptor.ts
import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { map, Observable } from 'rxjs';

@Injectable()
export class undefinedToNullInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    next: CallHandler<any>,
  ): Observable<any> | Promise<Observable<any>> {
    // controller 들어가기 전 부분의 코드는 이곳에 작성하면 됩니다.

    /* 
    controller 실행되고 난 후는 handle() 다음에 작성하면 됩니다.
    data는 controller에서 return해주는 데이터입니다.
    */

    return next
      .handle()
      .pipe(map((data) => (data === undefined ? null : data)));
  }
}

json은 undefined를 취급하지않고 null만 취급하기 때문에 undefined가 있으면 null로 바꿔주도록 하는 인터셉터입니다.

pipe 함수를 통하여 data의 형태가 변화됩니다.

pipe는 다음 포스팅을 참고하시면 됩니다. (아직 게시안했습니다)

 

그리고 Controller에 해당 인터셉터를 붙일 수 있습니다.

// article.controller.ts

@UseInterceptors(undefinedToNullInterceptor) // 추가된 부분
@ApiTags('게시글 API')
@Controller('article')
export class ArticleController {
  constructor(private readonly articleService: ArticleService) {}

  @ApiOperation({
    summary: '게시글 작성 API',
    description: '유저가 게시글을 작성한다.',
  })
  @ApiBody({
    type: CreateArticleDto,
  })
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Post()
  async createArticle(@Body() body: CreateArticleDto, @User() user) {
	...

    return article;
  }

이런식으로 적용하면 ArticleController 전체에 적용되지만, 컨트롤러의 함수 하나에 적용할 수도 있습니다.

@ApiTags('게시글 API')
@Controller('article')
export class ArticleController {
  constructor(private readonly articleService: ArticleService) {}

  @UseInterceptors(undefinedToNullInterceptor) // 추가된 부분
  @ApiOperation({
    summary: '게시글 작성 API',
    description: '유저가 게시글을 작성한다.',
  })
  @ApiBody({
    type: CreateArticleDto,
  })
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Post()
  async createArticle(@Body() body: CreateArticleDto, @User() user) {
    const userId = user.id;

    const title = body.title;
    const content = body.content;

    const article = await this.articleService.createArticle(
      title,
      content,
      userId,
    );

    return article;
  }

 

혹은, 이런식으로 Global하게 전체에 다 적용할 수도 있습니다.

//main.ts
app.useGlobalInterceptors(new undefinedToNullInterceptor());

또는 의존성 주입을 사용하여 전체에 적용할 수도 있습니다. (useGlobalInterceptors 말고 이 방법을 애용합시다)

@Module({
  ...
  providers: [
    ...
    {
      provide: APP_INTERCEPTOR,
      useClass: undefinedToNullInterceptor,
    },
    ...
  ],
})
export class AppModule {}

 

 

 

인터셉터는 아직 제가 많이 다뤄보지 않았기에, 여기까지만 작성하고 추후에 내용을 보충할 수 있다면 해보겠습니다.

 

 

여기까지 했다면, github에 push를 해봅시다.

 

https://suloth.tistory.com/46

 

#0-2. 기초부터 따라하는 Nest.js : Git과 Github 사용법

이 글은 아래의 포스팅에 이어서 작성하는 포스팅입니다. https://suloth.tistory.com/45 #1. 기초부터 따라하는 Nest.js : Nest.js 초기 설정 Nest.js란? node.js의 백엔드 프레임워크 중 하나입니다. node.js에는 수

suloth.tistory.com

 

참고하시라고 올려두는 사진입니다.