NestJS-Design Pattern

효딩딩·2023년 7월 18일
0

Nest(NestJS)

  • 효율적이고 확장 가능한 Node.js 서버 즉 애플리케이션을 구축하기 위한 프레임워크이다.

설치

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

package.json

  • nestjs안에서 자체적으로 동작하는 라이브러리이다.
"dependencies": {
    "@nestjs/common": "^10.0.0",
    "@nestjs/core": "^10.0.0",
    "@nestjs/platform-express": "^10.0.0",
    "reflect-metadata": "^0.1.13", //  @ 사용 시 사용되는 패키지 
    "rxjs": "^7.8.1",  // 리눅스, 맥에 rm -rf 명령어를 윈도우에서도 사용가능하게 해주는 패키지(특정 파일, 폴더 삭제 시 사용하는 메소드임)  
    "typeorm": "^0.3.17" // 이벤트 기반 프로그래밍을 작성하기 위한 라이브러리이다.

CLI nest 명령어를 사용하여 모듈 만들기

  • 공급자(Module)를 통해 sercice라는 제품을 받아 controller에서 service를 의존성 주입을 하여 사용한다.
  • 간단한 마이크로 서버를 개발할때는
    request -> middleware -> controller -> response 이렇게 레이어를 구성하기도 한다.
    NestJS CLI명령어
nest g co cats  // cats.controller.ts
nest g s cats   // cats.service.ts
nest g mo cats  //cats.module.ts

Controller

  • 컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환하는 역할을 합니다.
  • 브라우저에서 Http request 를 보내면 controller 가 받고 다시 controller가 브라우저에 response를 보내는 구조이다.

* 의존성 주입 : controller에서 service를 사용하기 위해 해주는것이고 이렇게 하는 이유는 유지보수, 가독성, 디자인 패턴에 맞게 하기위해서이다.

@ (데코레이터 패턴)

  • @Controller() 이렇게 사용한다. 반드시 붙여서 사용해야한다.
  • 함수나 클레스에 기능을 첨가해서 재사용성을 극대화해준다.

cats.controller.ts

import { Delete, Patch } from '@nestjs/common'
import { Controller, Get, Post, Put } from '@nestjs/common'
import { CatService } from './cats.service'


@Controller('cat')
export class CatsController {
 constructor( 
  	private readonly catsService : CatsService) {}

  // cats/
@Get()
 getAllCat() { return 'all cat' }

  // cats/:id
@Get(':id')
  getOneCat() { return 'one cat' }
  
  // cats/
 @Post() 
   createCat() { return 'create cat' }
  
 @Put(':id') 
   updateCat() { return 'update cat' }
  
 @Patch(':id') 
   updatePartialCat() { return;  }
 
 @Delete(':id') 
   updatePartialCat() { return 'delete cat' }
  
}

service

  • 실제 비지니스 로직을 담당한다.
  • 컨트롤러가 클라이언트의 요청을 처리하는데 필요한 작업을 처리한다.
  • 데이터베이스의 데이터를 가져오거나 외부 API 호출 등의 데이터를 처리한다.
  • @Injectable 데코레이터 사용 > 클래스가 주입가능한 상태로 변환
  • 함수 호출 후 return 해주면 controller가 그 리턴값을 받고 module로 들어가게 되고 module이 main.ts의 NestFactory로 들어가서 알아서 클라이언트가 해당하는 라우터에 가서 해당 값을 받을 수 있도록 설정해준다.

Module

  • provider : 공급자

* provider :
모듈을 생성하고, 의존성 주입 컨테이너에 추가할 클래스 인스턴스 또는 값의 배열.
주로 서비스와 리포지토리 등이 여기에 포함된다.
캡슐화가 되어있어(은닉화 되어서) 다른 모듈에서 기본적으로는 사용할 수 없다. 다른 모듈에서 접근할 수 있도록 exports 해주면 은닉화 된 것을 퍼블릭으로 바꿔주어 다른 모듈에서 사용할 수 있다.

  • controller : 모듈이 정의하는 컨트롤러의 배열, 컨트롤러는 클라이언트의 요청을 처리하고 적절한 응답을 반환하는 역할을 한다.
  • imports : 모듈이 의존하는 다른 모듈의 배열, Nestjs는 이러한 모듈들을 현재 모듈의 porvider와 controller가 사용할 수 있도록 제공한다.
  • exports : 모듈에서 제공하며, 다른 모듈에서 import하여 사용할 수 있는 porviders의 배열.
    상품들을 AppModule에서 사용할 수 있다.
import { Module } form '@nestsj/common'
import { CatsController } form './cats.controller'
import { CatService } form './cats.service'

@Module({
imports:[],
controller: [CatController],
providers: [CatService],
exports: [CatService]
        
})

export class CatModule

Middleware

  • 기본적으로 Express 미들웨어와 동일하다.
  • @Injectable() 있으므로 의존성 주입이 가능하다. 의존성 주입을 하면 미들웨어 적용이 가능하다.
  • 요청과 응답 객체에 접근하여 로깅, 인증, CORS 설정 등의 공통 작업을 처리하는데 사용된다.
  • 요청이 들어온 후 컨트롤러 및 다른 요소들에 앞서 실행된다.
  • 요청-응답 주기의 앞단에서 작동하여 공통 작업을 처리한다.

CLI를 통해 미들웨어 만들어주기

  • 요청하는 대상에 대해 어떤 대상이 어떤것을 요청했는지 찍어주는 로깅하는 미들웨어
  • 로깅 남기기 위한 로그 메세지 만들기
nest g middleware logger

app.module.ts

  • @Module() 에는 미들웨어를 위한 장소가 없어 configure() 모듈 클래스의 메서드를 사용하여 설정해야한다.
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('*'); // * 사용하면 전체 endpoint에 대해서 로거 미들웨어가 실행된다. 
  }
}

logger.middleware.ts

  • res 의 결과값도 로깅 : res.statusCode / 요청 시 정보, 반환 시 실패,성공 여부 한번에 로깅하기
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
 
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  pivate logger = new Logger('HTTP') // http 프로토콜에 관한 로거를 사용할 수 있게함. 
  
  
 use(req: Request, res: Response, next: NextFunction) {
// (1) console.log(req.ip, req.originalUrl);  Request 안에는 요청하는 대상의 정보가 담겨있음
// (2) this.looger.log(req.ip, req.originalUrl)  
// (3) this.logger.log(`${req.ip}, ${req.method},`,req.originalUrl);

// 미들웨어 → 라우터 → response 순 인데 response의 결과값도 같이 로깅을 해주자.
//  res.on('finish' ()=> {})  finish 이벤트를 이용해 response가 완료가 됬을 때라는 이벤트를 등록해주는것임. 
   res.on('finish', () => {
   this.logger.log(
        `${req.ip}, ${req.method}, ${res.statusCode}`, req.originalUrl, );
    });
    next();
  }
}
  
profile
어제보다 나은 나의 코딩지식

2개의 댓글

comment-user-thumbnail
2023년 7월 18일

정말 좋은 글 감사합니다!

답글 달기
comment-user-thumbnail
2023년 7월 18일

좋은 글 감사합니다!

답글 달기

관련 채용 정보