NestJs v7 -> v8로 업그레이드 후, 400 Bad Request 발생 시

NestJs에 socket.io와 websocket gateway를 사용하기 위해서 공식 문서에 나온 대로 진행하였다.

$ npm install @nestjs/websockets @nestjs/platform-socket.io

^8.00 이상은 필요하다고 에러가 발생하였다.

npm 패키지를 설치하는 부분부터 의존성 이슈가 발생하였다. 기존에 사용하던 nestjs와 관련된 모든 패키지의 메이저 버전이 7.x 였는데 최신 websocket 관련 패키지를 사용하려면, 최소한 nestjs 메이저 버전이 8.x는 되어야한다고....

 

기존이라면 nestjs 버전에 맞춰서 이전 버전의 패키지를 설치하겠지만, nestjs 버전 8과 버전 7의 socket.io의 버전이 메이저 버전 2.x와 4.x로 차이가 많이 발생하여 하는 김에 nestjs 공식 문서에 있는 migration guide를 보고, 메이저 버전 업데이트를 진행하였다.

 

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac

docs.nestjs.com

 

메이저 버전 8로 업데이트를 진행하고 나서, 쿼리를 통해 필터링 값을 front로부터 전달받는 API들에서 400 Bad Request: [0] items is not number. 라는 이슈가 발생하였다. 혹시나 해서 버전 7으로 롤백 후, 테스트를 해봤을 때는 정상적으로 필터링 값을 받아오는 것을 확인할 수 있었다.

문제가 된 코드는 아래처럼 *.controller.ts에서 발생하였다.

 

//users.controller.ts
@Get()
  users(
    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
    @Query('limit', new DefaultValuePipe(9), ParseIntPipe) limit: number,
    @Query(
      'tagIds',
      new DefaultValuePipe([]),
      new ParseArrayPipe({ items: Number, optional: true }), // 이슈가 된 부분
    )
    @Query('tagIds', new DefaultValuePipe([]))
    tagIds: number[],
    @Query('q') q: string,
  ){
  	// 서비스 호출 부분
  }

 

아무런 필터링 값이 전달되지 않았을 때, 기존의 버전 7.x에서의 new ParseArrayPipe의 경우, 빈 리스트 [ ]의 형태로 파싱했지만, 버전 8.x의 경우, optional: true 옵션이 적용되지 않는 것인지 빈 리스트가 아닌 null 값이 입력되어 400 Bad Request 에러가 발생한다.

 

해당 이슈가 발생한 부분의 ParseArrayPipe를 아래와 같이 변경하고, 프론트에서 해당 api 호출하는 부분의 tagIds에 [0]을 default Value로 넣는 방법을 통해 임시방편으로 400 에러를 해결하였다. 

 

//users.controller.ts
 @Get('users')
  users(
    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
    @Query('limit', new DefaultValuePipe(5), ParseIntPipe) limit: number,
    @Query('tagIds', new DefaultValuePipe([]), ParseArrayPipe) tagIds: number[],
    @Query('q') q: string,
  ) {
	// 서비스 호출 부분
  }