본문 바로가기

아카이브/dev-camp

dev-camp Day 1-1 : Shall We NestJS?

728x90

 

 

 

Nest.js를 만든 이유

아키텍처를 손쉽게 사용하기 위해 만들었다!

 

Nest Commands

dayoung@dayoungui-MacBookPro ~ % nest -h
Usage: nest <command> [options]

Options:
  -v, --version                                   Output the current version.
  -h, --help                                      Output usage information.

Commands:
  new|n [options] [name]                          Generate Nest application.
  build [options] [app]                           Build Nest application.
  start [options] [app]                           Run Nest application.
  info|i                                          Display Nest project details.
  add [options] <library>                         Adds support for an external library to your project.
  generate|g [options] <schematic> [name] [path]  Generate a Nest element.
    Schematics available on @nestjs/schematics collection:
      ┌───────────────┬─────────────┬──────────────────────────────────────────────┐
      │ name          │ alias       │ description                                  │
      │ application   │ application │ Generate a new application workspace         │
      │ class         │ cl          │ Generate a new class                         │
      │ configuration │ config      │ Generate a CLI configuration file            │
      │ controller    │ co          │ Generate a controller declaration            │
      │ decorator     │ d           │ Generate a custom decorator                  │
      │ filter        │ f           │ Generate a filter declaration                │
      │ gateway       │ ga          │ Generate a gateway declaration               │
      │ guard         │ gu          │ Generate a guard declaration                 │
      │ interceptor   │ itc         │ Generate an interceptor declaration          │
      │ interface     │ itf         │ Generate an interface                        │
      │ library       │ lib         │ Generate a new library within a monorepo     │
      │ middleware    │ mi          │ Generate a middleware declaration            │
      │ module        │ mo          │ Generate a module declaration                │
      │ pipe          │ pi          │ Generate a pipe declaration                  │
      │ provider      │ pr          │ Generate a provider declaration              │
      │ resolver      │ r           │ Generate a GraphQL resolver declaration      │
      │ resource      │ res         │ Generate a new CRUD resource                 │
      │ service       │ s           │ Generate a service declaration               │
      │ sub-app       │ app         │ Generate a new application within a monorepo │
      └───────────────┴─────────────┴──────────────────────────────────────────────┘

 

Controller

HTTP 요청을 받는 것

Get Post Put Delete 데코레이터를 제공
@Param @Body로 요청 객체의 정보 읽기

DTO로 입출력 정의

 

Provider

의존성 주입의 대상들 = Provider

@Injectable 데코레이터를 붙이면 Provider의 역할을 줄 수 있다!

그리고 Module의 명세에 적어 주어야 한다. 

 

의존성 주입의 장점

1. 추상과 구현이 분리되므로 코드가 유연해집니다.

2. 테스트 하기에도 편합니다.

 

 

Module

Module = 묶은 것

- imports : 갖다 쓸 모듈
- controllers : 외부 노출할 거
- providers : 의존성 주입할 거
- exports : 다른 애들이 쓸 거

 

 

@Global()

빈번히 쓰이는 모델 logger, config, databse....

글로벌 데코레이터를 넣으면 모두 가져다 쓸 수 있다. 

의존성을 깨기 때문에 제한적으로 사용해야 한다. 

 

Pipe

Transform : Input을 원하는 형태로 바꾸거나

Validation : 타당성을 검증하거나 

@nestjs/common에 들어가 있다!
적극적으로 사용 권유

ValidationPipe
PareIntPipe
ParseFloatPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
ParseEnumPipe
DefaultValuePipe

 

Schema-based validation

class-validator (@IsString() @IsInt() ... ) 와 함께 사용

 

CustomPipe

 

팀 스파르타에서 기술 스택을 교체하며 Nest.js를 선택한 이유

 

코드의 복잡도에 따라 더 많이 코드양이 늘어난다.

트리 구조로 바꾸자!

 

The Clean Architecture

의존성은 단방향

결론 : 헥사곤 아키텍처!

 

Hexagonal Architecture (헥사곤 아키텍처) = 포트/어댑터 패턴

창시자 : 알리스테어 코번

 

기존 Layered 아키텍처에서 영속성 계층으로 향하는 의존성을 역전시키는 것

- 외부에 의존하지 않는 도메인 로직을 가질 수 있음

 

내부 : 도메인 계층 - 순수 비즈니스 로직이 캡슐화된 영역

외부 : 기존 아키텍처에서 도메인 영역을 분리한 영역 (controller...)

 

숫자 6에는 큰 의미가 있지는 않다.

충분히 많은 수의 port와 adapter을 그리려고 하다 보니 육각형이 되었다. 

 

 

헥사곤 아키텍처의 장점

1. 기술 스택 변경 용이

2. API를 새로 뚫어주기 좋음
3. 테스트 하기 쉬움.

4. 외부 요인으로 인해 도메인 모델을 수정하지 않아도 됨.

 

Port/Adapter 패턴을 사용하는 이유

Adapter의 생김새가 상이한 이유

= 도메인으로서 의존성을 가르키기 위함입니다. 

 

Port

Port = Interface

도메인을 사용하는, 서비스 함수가 사용할,

즉 내부 영역이 외부 영역에 노출하는

유즈케이스에 대한 규칙을 정하는 것

 

Adapter

Infra Structure와 Port 사이에 커뮤니케이션

동일한 포트(use case)에 다른 인프라스트럭쳐 컴포넌트를 얹으려면.

 

In/Out

In 도메인이 들어오는 요청에 대한 것이라면

Out 도메인이 외부로 요청하는 것이라면

In Port
Out Port

 

In Adapter

실제 인터페이스의 구현이 도메인 내부에 있다. 

외부 어댑터는 단순히 그 구현을 사용한다. 

 

Out Adapter

In과는 반대로 어댑터에서 실제 인터페이스 구현이 발생.

도메인 계층에서는 그것을 사용하기만 한다.

 

Service 계층

Out Port의 사용처

In Port의 구체적인 구현처

 

예시)

 

참고 자료 : https://youtu.be/AHSHjCVUsu8?si=4aFHXFCHxNqK0Cnk