똑같은 삽질은 2번 하지 말자

NestJS vol.2 본문

카테고리 없음

NestJS vol.2

곽빵 2023. 1. 23. 22:25

개요

NestJS를 배우면서 남기는 기록

 

Nest CLI 활용

NestJS 특성상 모듈 컨트롤러 서비스의 사용이 규격화 되어있기 때문에 개발자들이 더욱 쉽게 사용할 수 있게끔 이러한 파일들을 자동으로 생성하고 연결해주는 CLI가 몇개 있다.

nest generate module users

nest generate service users

nest generate controller users

이렇게 명령어를 입력해주면 이하의 사진처럼 파일을 생성하고 app.module에 연결시켜준다.

 

NestJS의 Convention

  • 파일의 이름은 도메인명.기능.ts로 주로 쓰이며 예를들면 users.controller.ts, users.service.ts
  • 타입은 Interface보단 class를 이용해 런타임에도 활용할 수 있게한다.
  • export default 보다 export를 쓴다.

 

OpenAPI

nestjs의 장점중 하나로 자동으로 API에 대한 문서를 만들어준다.

https://docs.nestjs.com/openapi/introduction

 

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

위의 공식문서를 읽고 따라서 해보면

이렇게 자동으로 생긴다!

하지만, 자동으로 안 생기는 부분들은 Swagger 패키지에서 @ApiTags같은 데코레이터를 이용해서 명세를 해줘야 조금더 내용이 알찬 API 문서를 만들 수 있다. (dto를 활용해서 req의 body나 response의 형태를 쓰는것도 가능하다.)

 

Custom Decorator

controller에서 @Req req 해서 요청객체를 접근하는 경우가 있는데 @Req나 @Res는 express의 req, res의 기능에 종속적이기 때문에 내부의 express에서 fastify로 코어를 교체하거나 컨트롤러 테스트를 작성할 때 @Req로 인한 결합도가 올라가므로 안 좋을 수 있다. 이를 최대한 줄여주기 위해서 커스텀 데코레이터로 대체하면 좋다. 그에 대한 과정을 기록해보자

 

내가 만들고 싶은 데코레이터는 req의 param으로 들어오는 부분을 취득하는 기능을 하는 친구이다.

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator((data, ctx: ExecutionContext) => {
  const request = ctx.switchToHttp().getRequest();
  return request.user;
});
  • nest에서 제공하는 createParamDecorator를 활용하면 쉽게 만들 수 있다.
  • ExecutionContext는 JS의 그것과는 상관없이 지금 nest 실행환경을 뜻하는 변수로써 다양한 정보가 들어있다.

활용할 때는

export class UsersController {
  @ApiOperation({ summary: '내 정보 가져오기' })
  @Get()
  getUsers(@User() user) {
    return user;
  }
}

이렇게 하면 된다.

 

Interceptors

NestJS에서 AOP의 개념을 바탕으로 생겨난 기능이다.

 

먼저 AOP란?

Aspect Oriented Programming 의 약어로 관점 지향 프로그래밍이다.

어떤 일련의 처리들에 있어서 공통적으로 가지는 부분(관점)을 흩어지게 두지 말고 응집해서 관리를 하기 위한 기술이다.

 

이런 AOP의 개념을 바탕으로 생겨난 NestJS의 Interceptor는 이하의 기능들이 있다.

  • 메서드 실행 전/후에 추가 로직 바인딩
  • 함수에서 반환된 결과 변환
  • 함수에서 발생한 예외 변환
  • 기본 기능 동작 확장
  • 특정 조건에 따라 함수를 완전히 재정의합니다(예: 캐싱 목적).

여기서 함수에서 반환된 결과 변환을 실제로 만들어 보려고 한다.

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>> {
    // before controller에 들어오기 전

    // after controller에 들어오고 난 후 데이터를 리턴할 때
    return next
      .handle()
      .pipe(map((data) => (data === undefined ? null : data)));
  }
}

json에서는 undefined라는 값 자체가 존재 안하므로 그걸 null로 바꿔주는 처리이다.

( 여기서의 관점은  undefined => null 로 변환 )

 

좀더 자세한 설명은 역시 공식문서에서 보자

https://docs.nestjs.com/interceptors

 

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

 

Comments