본문 바로가기

모카 스터디/Nest

NestJS 개요 및 객체지향 디자인 패턴

https://www.inflearn.com/course/%ED%83%84%ED%83%84%ED%95%9C-%EB%B0%B1%EC%97%94%EB%93%9C-%EB%84%A4%EC%8A%A4%ED%8A%B8/dashboard

 

탄탄한 백엔드 NestJS, 기초부터 심화까지 - 인프런 | 강의

Java에는 Spring이 있고 Python에는 Django가 있다면 Node에는 NestJS가 있습니다! 프로페셔널한 Node의 백엔드 NestJS와 Node 객체지향 프로그래밍 및 디자인 패턴을 배우세요! 이 강좌는 멤버십 구독 강좌이

www.inflearn.com

윤상석 님의 NestJS 강읠르 토대로 한 기록 포스팅 입니다.

 

NestJS 개발 환경 셋팅

 

setup

$ npm i -g @nestjs/cli
$ nest new project-name

그러면 기본적인 세팅이 이루어진채 노드모듈 및 기타 필요한 파일들이 설치되고 src도 생성되어있다.

package.json에 이미 많은것들이 설치되어있다.//nestjs에 필요한 코어 모듈들.

개발에서 많이 쓸 명령

   "start:dev": "nest start --watch",
   "start:debug": "nest start --debug --watch",
    
프로덕션할때 사용할 명령어

   "start:prod": "node dist/main",

controller는 express의 라우터 이다.                    router.get('/',...)------->@ Get('/') getHello()

데코레이터 : 함수나 클래스에 기능첨가를 해주는것.

 

app.service에서 비지니스로직이 실행이 되고 익스프레스와 달리 res.send가 아닌 nest에서는 return으로 바로 보낼 수 있다.

그 리턴값을 controller가 받고 그게 다시 module로 반환되어 들어간다.

그리고 그 모듈이 main.ts에서 NestFactory로 들어간다.

그리고 알아서 자동으로 클라이언트가 해당하는 라우터로 들어가서 받을수 있도록 된다.

 

postman으로 get을 통해 요청을 보내면 hello world!가 나온다.

첫번째 main.ts에서 bootstrap으로 app이 실행이되고   그 app은 appModule로 만들어 졌다.

app.module에 appController가 존재하고 그 컨트롤러로 들어가면

getHello라는 메소드가 실행하도록 하는 코드가 있고 리턴값으로 service에 있는 getHello라는 메소드의 값인걸 알 수 있다.

그리고 service에서 그 값을 확인 할 수있다.

 

NestJS구조&Controller패턴

nestjs/로 시작하는 상위 3개는 nestjs 내부에서 자체적으로 동작하는 라이브러리이다.

reflect-metadat :   @데코레이터 문법을 사용하기 위한 라이브러리

rimraf : 맥이나 리눅스에서도 rimraf명령어 사용하게(삭제)

rxjs : 비동기 이벤트기반 프로그래밍을 작성하기위한 라이브러리.

 

컨트롤러

컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환하는 역할을 합니다 .

 

컨트롤러에서 바로 return 해주면 될 텐데 왜 굳이 service로 넘길까 ?

 

이유 : 유지보수와 가독성 위한 디자인 패턴+ nest는 모듈 단위로 이동.

하나하나가 클래스이고 그 클래스가 레고처럼 결합해서 모듈을 이룬다.

그 모듈들이 모여서 다른 하나의 모듈이 되고 그 모듈이 main에서 실행.

 

또한 컨트롤러의 목적은 애플리케이션에 대한 특정 요청을 수신하는 것이다.

req와 param도 받아올 수 있다.

 

req.body나req,param으로 사용할 수 있지만

더욱 확실하게 책임을 지게하기 위해

따로데코레이터를 사용하여 컨트롤 가능.

 

EX) @Body() body, @ Param() param

 

 위와 같이 Param 활용가능.

 

Body는 DTO라는것을 작성하는게 낫다.

그 DTO내에서 body에 대해 validation을 처리할 수있다.

 

 

     

Providers&의존성 주입(DI)

파일을 불러오는 express와 달리 nest는 클래스의 생성자로 초기화 한 후 인자로 바로 사용했다.

보통은 this.appservice=appservice로 생성자 내에서 초기화를 하지만 nest에서는 typeScript를 문법을 써서 중괄호 생략.

이러한것을 의존성 주입, Dependcy Injection이라고한다.

 

controller를 소비자라 생각을하고  service를 제품이라고 생각을해보자. 

또한 제품을 생성하는 provider가 따로 있다. 

제품을 사용자 입장에서 사용을 한다 -->  컨트롤러 단에서 return this.appService.getHello(); (컨트로러에서 서비스단을 사용.)

 

즉, service단(+ 차후에 나올 레포지토리)이 provider이다.

 

그리고 그 공급자(provider)로 취급이 된것 들은 @injectable 데코레이터를 사용해서 의존성을 주입해 줄 수 있다.

 

nest는 의존성을 코드에 남김으로 확실하게 의존성 관리를 할 수 있다.

 

 

 

Modules&캡슐화

nest 명령어를 통해서 모듈을 만들 수 있다.    ==> nest g mo cats

그럼app.module에서 자동으로 import가 되며 cats라는 폴더가 cats.moduel.ts를 가진채  src 내부에 생성된다

 

nest g co cats                                                                        nest g s cats     

그럼 cats내부에 controller관련 파일이 생성된다.                     그럼 cats내부에 services 관련 파일이 생성된다.

 

import를 하면 [ ]사이에 있는 모듈내에서 exports를 한 상품,제품(service, repositoy)를 쓸 수 있다.

 

원래 CatsService는 캡슐화되어서 외부에서 사용을 못하지만

exports 해주면 외부(app.module이나 user.module)에서 사용가능==> 외부에서 여러개의 의존성 주입가능.

 

Nest Middleware

미들웨어는 라우트 핸들러 보다 먼저 호출

 

>nest g middleware logger

그리고 app.moduel.에 연결한다.

@Module 데코레이터에는 미들웨어를 위한 장소가 없다.

대신 configure()모듈 클래스의 메서드를 사용하여 설정한다.

미들웨어를 포함하는 모듈은 NestModule 인터페이스를 구현해하하며 LoggerMiddleware에서 설정을 한다.

 

주로 nest에서 제공해주는 LOGGER사용

 

 

 

 

res 객체의 on 메서드를 사용하여 finish 이벤트가 발생 했을때

즉, 응답까지 끝낸 후 response에 대한 결과값도 logging한다.

 

 

 

Exception fillter&Pipes

 

nest에서 제공하는 기본 에러 시 응답 형식이다.

 

하지만 다른 정보 혹은 더 많은 정보를 응답해줘야 할 때가 있다.

 

 

 

throw new HttpException('API에 문제가 있습니다.',401);     

이라고 에러 메세지와 status code를 인자로   nest에서는 주로 에러를 던진다.

그러면 왼쪽과 같은 응답형식으로 응답이 나온다.

또한 아래와 같이 json을 커스텀을 해서 응답을 보내줄 수 있따.

 

하지만 위와 같이 다른 형식은 똑같이 유지하되 message만 다르게 보내고 싶을 때 중복이 많이 발생한다.

 

이럴때 아주 좋은 기술인  Exception fillter&Pipes를 사용하면 개꿀딱이다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

가장 윗줄이 express에서 주로 사용하던 형태이고

 

아래의 nest에서의 방식이다.

 

 

왼쪽 처럼 각각의 컨트롤러에서 필터를 적용 시킬 수 있고    오른쪽 사진처럼 전체의 모든 에러에 대해서도 필터를 적용 시킬 수 있다.

 

exception이라는 객체에 있는 다양한 메소드중

getResponse라는 메서드를 사용하여 이전 httpException의 인자로 보낸 문자를 응답으로 보내줄 수 도 있다.

 

 

다양한 기능을 활용할 수 있을 꺼같다.

차후 필요시 하나씩 콘솔로 찍어보며 찾아보면 될듯

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

error의 값이 Object 또는 string일 경우 따라 분기를 나눠

nest자체적으로 에러에 대한 응답과  httpException를 사용해서 직접 인자로 메세지를 넣어준 경우를 처리 해 줄 수 있다.

그러면 아래와 같이 커스텀하여 처리한 에러들을 이뿌게 커스텀 할 수 있다.

 

Pipe

클라이언트 요청에서 들어오는 데이터를 유효성 검사 및 변환을 수행하여 서버가 원하는 데이터를 얻을 수 있도록 도와주는 클래스.

 

왼쪽과 같이 원하는 값이 아닌 경우  validation에러까지 낼수 있다. 일석이조 개꿀따락지.

 

여러가지 파이프들이 많으며 class-validator라는 개꿀 라이브러리가 있으므로 나중에 따로 살펴 보자.

 

파이프를 커스텀할 수도 있다.

 

transform이라는 함수의 결과 값이 

파이프의 결과값이다.

 

 

 

 

입력 값이오면 파이르로 꼬리에 꼬리를 물어 데이털르 처리 할 수 있다.

 

 

Interceptors  &  AOP(관점지향 프로그래밍) 패턴

인터셉터는 @Injectable() 데코레이터로 주석이 달린 클래스이다.

인터셉터는 NestInterceptor 인터페이스를 구현해야한다.

세로 막대는 각각의 라우터라고 생각.                 

가로 막대는 각 라우터 별로 공통적으로 필요한 기능   EX) 로깅 기능

인터셉터는 크게 컨트롤러 전화 컨트롤러를 지난 후로 나뉜다.

 

 

Request 라이프 사이클( life Cycle)