본문 바로가기
Node js/Nest js 강의 내용

3. Nest 프로젝트 생성 및 예상 아키텍처

by Bill Lab 2024. 12. 6.
728x90

1. 설치

     (1) 설치 명령어(기존에 설치하지 않은 경우에만)

이미지출처 : 위키백과(yarn)

     (pnpm 을 권장드리나, yarn이나 npm 이 편할 경우 사용해도 됨)

 

pnpm i -g @nestjs/cli

     (강의 내용은  npm i -g @nestjs/cli@10.4.8 버전 기반)

nest new commerce

   nest 명령어를 사용하여, nest 프로젝트를 생성해보자

 

   또는

 

   git clone 으로 Nest 프로젝트 시작가능

git clone https://github.com/nestjs/typescript-starter.git project
(cd project)
yarn install 
(pnpm 사용해도 됨)

 

     (2) 빌드 명령어

npm run build or yarn build or pnpm build

 

 

     (3) 실행 명령어(설치 및 기본동작 잘되는지 확인)

npm run start or yarn start or pnpm start

 

 

 

2. Nest 기본 architecture

    (1) nest 공식문서에서 제공하는 architecture

         - 가장 기본인 nest 공식 가이드 문서 참고하여 소스 레이어 architecture 를 추가해보자

         - 모듈을 기반으로 해서, "controller, sesrvice, repository" 등이 추가되는 구조 

         - Dependency Injection 전 모듈 지원

         - Global modules 및 Dynamic modules 지정 가능

출처: nest 공식 사이트

 

     (2) 명령어

           : 이전에는 각각 생성했던 것이, 최근에는 아래의 명령어로 관련된 privider, entity 까지 한번에 생성이 가능하다.

            (도메인 관점에서 orderDetail은 order 모듈안에서 같이 개발 예정)

nest g resource order
nest g resource cart
nest g resource product

     (nest 버전 업데이트를 하고 나야 위의 명령어가 제대로 작동한다)     

 

 

(3) package.json 에 대해서

           (^ 의 의미: 업데이트 가능 버전: 10.x.x  즉, 10으로 시작하는 모든 최신 버전)

           코드 추가 예정

 

 

3. 객체지향 프로그래밍(OOP)의 SOLID 원칙

1) DRP(Single Responsibility Principle, 단일책임 원칙)

    : 작성된 클래스는 하나의 기능만 가지며, 클래스가 제공하는 서비스는 하나의 책임을 수행하여야 한다.

     (역할 및 책임을 클래스 마다 분리!)

      

   

2) OCP(Open Close Principle, 개방폐쇄 원칙)

    : 확장에는 열려있고 변경에는 닫혀 있어야 한다.

      

 

3) LSP(Liskov Substitution Principle, 리스코브 치환 원칙)

    : 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 한다.

      

 

4) ISP(Interface Segregation Principle, 인터페이스 분리 원칙)

    : 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다

      

 

5) DIP(Dependency Inversion Principle, 의존관계 역전 원칙)

    : 프로그래머는 추상화에 의존해야지 구현체에 의존하면 안된다.

     

 

4. 함수형 프로그래밍(Functional Programming)  

    : 대부분을 순수함수로 나누어 문제를 해결하는 기법

      함수형 프로그래밍에서는 값이 변하지 않는 불변성(Immutable Data)을 통해, 코드의 예측 가능성과 안정성을 극대화

      하며, 특히 병렬 처리 환경에서의 경쟁 조건(Race Condition)을 최소화한다.

      Nest 의 함수형 프로그램밍은 함수를 수학적 계산이나 식으로 봄!

 

     1) 함수형 프로그래밍의 핵심

          : 부수효과가 없는 순수 함수(Pure Function)를 1급 객체로 다루어, 이를 파라미터나 반환값으로 자유롭게 사용

            참조 투명성(Referential Transparency)을 유지하는 데 있다.

     

      2) 목적

          : 외부 상태와 독립적으로, 입력에 따라 항상 동일한 출력을 제공하며, 프로그램의 동작을 예측 가능하고

            명확하게 만든다.

 

      3) 부수효과(Side Effect)

           : 변수 변경, 자료 구조의 수정, I/O 작업 등 외부 상태를 변화시키는 행위로 정의된다.

 

      4) 순수 함수 

           : 부수효과를 배제한 함수로, 외부에 영향을 주지 않으므로 멀티스레딩 환경에서도 안전하고, 병렬 처리 시 동기화

             없이 안정적인 결과를 보장한다.

 

      5) 1급 객체

           : 1급 객체 함수는 변수나 데이터 구조에 저장하거나 다른 함수의 파라미터로 전달하고, 반환값으로 사용할 수 있다.

             이는 함수형 프로그래밍이 제공하는 강력한 유연성과 추상화를 가능하게 한다.

 

      6) 참조 투명성

          : 동일한 입력에 대해 항상 같은 결과를 반환하는 성질로, 프로그램의 상태 변화가 없음을 의미한다.

    

 

5. 함수 반응형 프로그래밍(Functional Reactive Programming)

     : 함수형 프로그래밍과 반응형 프로그램밍을 결합한 형태(비동기나 이벤트 처리 지원)

       (async / await, RxJS - Observable)

 

 

6. 개발예정 Architecture

(개발공부시에는 .eslintrc.js 내 'plugin:prettier/recommended', 부분을 제거하자)

그럼 결과는? (현업레벨에 적합하게 수정한 architecture)

    1) 모듈을 도메인 관점에서 분리를 진행

    2) 각 모듈별로 layer가 명확히 구분되고, 확장성을 고려한 폴더 tree 추가(presentation, domain. infra 등)

    3) controller 전용 dto와, domain 전용 dto를 분리

    4) 모듈별로 언제든지 micro service 로 분리시킬 수 있도록한 구성

- 물론 application 구조는 끝나지 않는 논쟁 사항 중 하나이고 한가지 방법만 존재하는 것도 아니다!

  (그렇지만, 잘되어있는 구조를 모방하여, 개선해 나가는 것은 매우 중요하다.)

 

(번외) 왜 처음설계 부터가 중요한가?

"향후 서비스가 확장되게 되면, 그때 처음부터 다시 개발하면 되는것이 아닌가? 라고 생각할 수도 있을 것이다.
하지만 그렇게 하게 되면, 시스템의 안정성을 100프로 보장할 수 없다.(QA가 테스트를 하던 개발자가 테스트 코드를 잘 작성했을 시 일부 오류를 막을 순 있겠지만, 시스템 장애에 대한 리스크는 여전히 클 수 밖에 없다.)
그렇기 때문에 가장 이상적인 것은 기존 시스템이 확장에 열려있는 구조이면서, 테스크코드를 최대한 유지한채 리펙토링이 가능한 형태로 설계해야 한다는 것이다.
728x90