ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nest.js 개요와 라이프 사이클
    카테고리 없음 2022. 2. 9. 17:33

    Nest.js 개요


    • Nest.js는 Node.js의 프레임 워크이다. 확장이 쉬우며, rest-api, graphql, microservice(non-http), websocket 의 템플릿을 cli 를 통해 자동으로 생성 해준다.
    • Express/Fastify 기반의 서버를 제공한다.
    • IoC를 구현 하는 프레임 워크로, 객체를 관리하고 생성을 책임지고 의존성을 관리하는 컨테이너이다.
      • IoC란 제어의 역전 이란 말인데, 메서드나 객체의 호출작업을 개발자가 결정하는 것이 아니라 제어권을 제 3자(컨테이너) 에게 위임하는 것이다.
      • DI와 밀접하게 관련이 되어있는데 아래 사진을 참고하면 될듯 하다.

     

    Nest.js 라이프 사이클


    기본적인 순서는 다음과 같다.

    Middleware => Guards => Pre-Interceptors => Pipes => Controller => Service => Post-Interceptors => ExceptionFilter => Response 

     

    1. Middleware 

    전역으로 바인딩 되어있는 미들웨어를 가장먼저 실행 한다. (main.ts 에 app.use로 바인딩 되어있는 미들웨어들)

    Express와 비슷한 방식으로 바인딩 된 순서대로 순차적으로 실행 된다.

      app.use(cookieParser(process.env.SESSION_SECRET));
      app.use(helmet());
      app.use(helmet.xssFilter());
      app.use(helmet.noSniff());
      app.use(helmet.hidePoweredBy());
      app.use(helmet.referrerPolicy());
      app.use(bodyParser.json());

     

    2. Guards

    사용자의 권한을 체크하는 로직이 들어간다 예를들어 jwt를 사용한다면 @UseGuards()를 통해 jwt의 값이 유효한지 검사 할 수 있다. 

    import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
      canActivate(
        context: ExecutionContext,
      ): boolean | Promise<boolean> | Observable<boolean> {
        const request = context.switchToHttp().getRequest();
        return validateRequest(request);
      }
    }

    다음과 같이 Guards를 정의 해놓으면 컨트롤러에선 이렇게 사용 할 수 있다.

     

    @Controller('cats')
    @UseGuards(RolesGuard)
    export class CatsController {}

    3. Interceptor

    인터셉터는 컨트롤러에 접근하기 전, 후에서 바인딩 시킬 수 있다.

    컨트롤러에 전에 접근하기 전에 사용하려면 return 전에 사용을하면 되고 컨트롤러 접근후에 사용하려면 return 문에서 사용하면 된다.

     

    import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
    import { Observable } from 'rxjs';
    import { tap } from 'rxjs/operators';
    
    @Injectable()
    export class LoggingInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        console.log('Before...');
    
        const now = Date.now();
        return next
          .handle()
          .pipe(
            tap(() => console.log(`After... ${Date.now() - now}ms`)),
          );
      }
    }

     

    그리고 컨트롤러에 Guard와 동일하게 걸어놓으면 된다.

     

    @UseInterceptors(LoggingInterceptor)
    export class CatsController {}

    4. Pipes

    요청이 들어오는 파라미터의 validation 혹은 형변환이 필요할 때 파이프에서 진행 한다.

    @Get(':id')
    async findOne(@Param('id', ParseIntPipe) id: number) {
      return this.catsService.findOne(id);
    }

    5. Controller

    routing ,http method, Request에 담긴 페이로드, Response에 담을 페이로드를 Controller에서 관리할 수 있다. 

    import { Controller, Get, Req } from '@nestjs/common';
    import { Request, Response } from 'express';
    
    @Controller('cats')
    export class CatsController {
      @Get()
      findAll(@Req() request: Request, /*@Res() response: Response*/): string {
        return 'This action returns all cats';
      }
    }

     

    6. Service

    실제 비지니스 로직을 Service 단 에서 관리 할 수 있다.

    import { Injectable } from '@nestjs/common';
    import { Cat } from './interfaces/cat.interface';
    
    @Injectable()
    export class CatsService {
      private readonly cats: Cat[] = [];
    
      create(cat: Cat) {
        this.cats.push(cat);
      }
    
      findAll(): Cat[] {
        return this.cats;
      }
    }

     

    7.  ExceptionFilter

    익셉션 필터는 로직을 처리하다가 오류가 발생 하면 HttpException을 throw 하게 된다.

     

    @Get()
    async findAll() {
      throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    }

     

    댓글

Designed by Tistory.