NestJS

    모듈 간의 순환참조

    모듈 간의 순환참조

    Nest.js를 사용해서 개발을 진행하다보면 도메인 모델 계층에서 정말 많은 모듈로 분리해서 개발을 진행하게 된다. 명확한 명칭으로 모듈을 분리하게 되면 해당 모듈이 어떤 역할을 하는지 쉽게 알 수 있어 매우 좋지만 서로 다른 모듈끼리의 의존성을 조금만 신경쓰지 않으면 순환참조와 같은 문제가 발생한다. 순환참조란? 순환참조는 객체, 데이터, 모듈, 함수 등이 서로를 참조하는 것을 말한다. 간단한 자바스크립트 코드로 예시를 들면 아래와 같다. let obj1 = {}; let obj2 = {}; obj1.otherObj = obj2; obj2.otherObj = obj1; 이처럼 서로를 참조하는 경우 프로그램의 복잡성을 증가시키고 디버깅을 어렵게 만든다. 또한 메모리 누수, 스택 오버플로우, 무한 루프 ..

    Nest.js 라이프사이클

    Nest.js 라이프사이클

    최근에 Nest.js 라이프사이클에 대한 질문을 받은 적이 있었다. 런타임 때나 통신이 일어날 때 타이밍에 맞는 라이프사이클이 있다는 것은 알고 있었지만 제대로 정리해 본 적이 없어 정리된 대답을 하지 못했다. 그래서 개념을 다시 정리하려고 한다. 1. Lifecycle 먼저 Nest.js documentation 을 보면 아래와 같은 그림이 나와있다. 제일 위부터 보면 Bootstrapping starts에서 런타임이 시작되고 아래 여러 가지 이벤트를 지나서 Application is running에 도달해서 서비스가 돌아가기 시작한다. onModuleDestroy부터는 서비스를 종료한다는 신호를 보냈을 때 일어나는 이벤트 들이다. 1-1. Lifecycle Events 위 그림에서 검은색 바로 되어있..

    Express에서 DI 프레임워크 만들어보기

    Nodejs 진영에서 DI/IoC를 사용해 서버를 구축하기 위해선 DI 프레임워크인 Nestjs를 사용하거나 Express에서 typedi를 활용해 서버를 구축해야 한다. Nestjs에선 데코레이터(@)와 Module을 활용해 의존성들의 관계만 신경 써주면 쉽게 주입받아 관리할 수 있고, Express에서 typedi로 의존성을 관리하는 것도 비슷하다. (@Service 데코레이터를 통해서 IoC 컨테이너에 자동으로 등록되고 런타임 때 typedi를 통해 알아서 주입받아 사용하는 형태다) 최근 들어 Nestjs에서 데코레이터를 커스텀해 사용할 일이 많아지다 보니 도대체 데코레이터의 동작원리가 어떻게 된 건지 궁금해졌다. 하지만 Nestjs에서 제공하는 커스텀 데코레이터 메서드들은 한번 더 추상화된 메서드..

    Nest.js에서 모듈간의 의존성 관리하기

    Nest.js를 사용해서 개발하게 되면 도메인 모델을 기준으로 수많은 모듈이 생기게 된다. 도메인 모델 별로 나누기 때문에 해당 파일이 어떤 역할을 하는지 명시적으로 알 수 있어 매우 편리하지만 서로 다른 모듈끼리 의존성을 관리해줘야 한다. 서로 다른 모듈의 의존 관계 설정 아래는 예시 코드이다. // user.module.ts import { Module } from '@nestjs/common'; import { UserService } from './user.service'; @Module({ providers: [UserService], exports: [UserService], }) export class UserModule {} // auth.module.ts import { Module } ..

    AuthGuard 예외처리 조건 만들기

    AuthGuard는 Nestjs에서 제공하는 미들웨어이다. AuthGuard는 Strategy와 사용되는데 보통 Passport 라이브러리를 활용하여 다양한 인증 전략을 구성할 수 있게 해 준다. 아래는 예시 코드이다. 보통 Controller layer에서 데코레이터를 활용해 사용할 수 있다. (라우터에서도 사용 가능함) 여기서 'jwt'는 Passport를 활용해 작성된 Strategy이고, 거기에 decorator로 만든 user.decorator까지 사용하게 되면 http 통신이 올 때 먼저 토큰 검증부터 진행할 수 있다. // Controller layer @Controller('example') export class ExampleController { constructor(private ex..

    Nest.js 에서 역직렬화 하기

    최근까지 repository 계층에서 리턴되는 타입에 entity를 그대로 사용했었다. 하지만 단위 테스트를 작성하다 보니 entity를 타입으로 지정하면 테이블 조인되어 있는 부분까지 명시해줘야 하는 불편함이 있었다. 이에 아웃풋 타입 DTO를 작성해 하려다보니 계속해서 실제 리턴타입과 명시된 아웃풋 DTO가 다르다는 에러가 발생했다. 내가 모르는 리턴 타입에 대한 DTO 작성 방법에 대해 찾다 보니 역직렬화에 대해 알 수 있었다. 역직렬화를 말하기전에 직렬화에 대해서 말하자면 객체(class) 형태의 데이터를 json 형태로 변환하는 과정이다. http 통신을 통해 데이터를 주고받을 때 json으로 주고받기 때문에 서버로 넘어온 데이터를 직렬화를 통해 객체(class) 형태로 바꿔주기 위해 필요한 ..

    Nest.js custom decorator 사용하기

    nestjs에선 decorator에 대한 여러 가지 기능을 제공한다. 먼저 request에 해당하는 부분에 데이터를 데코레이터를 사용해 핸들링할 수 있고, 여러 데코레이터들을 하나로 묶는 기능도 제공한다. 1. request 관련 데이터 커스텀 데코레이터 사용하기 import { createParamDecorator, ExecutionContext } from '@nestjs/common'; export const User = createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.user; }, ); 해당 코드는 nestjs 공..

    @nestjs/config 사용하는 이유

    보통 프로그래밍을 할 때 노출되면 위험한 민감한 정보들은. env 파일에 담아두고 사용하게 된다. 이렇게 환경변수로 담아두고 사용하게 되면 테스트 환경이나 개발 환경, 배포 환경으로 나눠서 사용할 수 있다. nestjs에서도 상황에 맞게 가져와 사용할 수 있게끔 라이브러리 @nestjs/config를 제공한다. @nestjs/config 설치 npm install @nestjs/config ConfigModule Root module에 등록하기 configMoudle을 사용하기 위해선 Root module에 등록하고, 이때 isGlobal 옵션을 true로 설정하면 하위에 있는 모든 모듈에서 쉽게 주입받아 사용이 가능하다. 만약 옵션은 false로 지정하면 매번 다른 모듈에서 imports에 등록해줘야 ..