IT/쇼핑몰

NestJs 개념 잡기- 볼 때 마다 어려워서 정리다 정리

higold 2024. 9. 24. 06:30

NestJS 기본 개념: 확장 가능한 Node.js 애플리케이션 구축하기

목차

  1. NestJS 소개
  2. 주요 개념
  3. 의존성 주입
  4. 데코레이터
  5. 예외 처리
  6. 파이프
  7. 가드
  8. 인터셉터
  9. 결론

NestJS 소개

NestJS는 효율적이고 확장 가능한 Node.js 서버 측 애플리케이션을 구축하기 위한 프레임워크입니다. TypeScript를 완벽하게 지원하며, 객체지향 프로그래밍(OOP), 함수형 프로그래밍(FP), 함수형 반응형 프로그래밍(FRP)의 요소를 결합합니다. Angular에서 영감을 받아 설계되었지만, Node.js 생태계의 다양한 라이브러리를 활용할 수 있습니다.

NestJS는 Express와 같은 강력한 HTTP 서버 프레임워크를 기반으로 하며, 선택적으로 Fastify를 사용할 수도 있습니다. 이를 통해 개발자는 기존 Node.js 생태계의 많은 서드파티 모듈을 그대로 사용할 수 있습니다.

주요 개념

모듈

모듈은 NestJS 애플리케이션의 기본 구성 요소입니다. 관련된 기능을 그룹화하고 구조화하는 데 사용됩니다. 각 애플리케이션에는 최소한 하나의 루트 모듈이 있어야 하며, 이를 중심으로 여러 기능 모듈을 구성할 수 있습니다.

모듈은 @Module() 데코레이터로 주석이 달린 클래스입니다. 이 데코레이터는 Nest가 애플리케이션 구조를 구성하는 데 사용하는 메타데이터를 제공합니다.

예시:

@Module({
  imports: [OtherModule],
  controllers: [MyController],
  providers: [MyService],
  exports: [MyService]
})
export class MyModule {}

컨트롤러

컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환하는 역할을 합니다. 라우팅 메커니즘은 어떤 컨트롤러가 어떤 요청을 수신할지 제어합니다.

컨트롤러는 @Controller() 데코레이터로 클래스를 장식하여 정의됩니다. 이 데코레이터는 관련 라우트들의 공통 경로 접두사를 허용합니다.

예시:

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

프로바이더

프로바이더는 NestJS의 기본 개념입니다. 대부분의 기본 Nest 클래스(서비스, 리포지토리, 팩토리, 헬퍼 등)는 프로바이더로 취급될 수 있습니다. 프로바이더의 주요 아이디어는 의존성으로 주입될 수 있다는 것입니다.

프로바이더는 일반적으로 @Injectable() 데코레이터로 주석이 달린 클래스입니다.

예시:

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}

미들웨어

미들웨어는 라우트 핸들러 이전에 호출되는 함수입니다. 미들웨어 함수는 요청 및 응답 객체에 액세스할 수 있으며, 애플리케이션의 요청-응답 주기에서 next() 미들웨어 함수에 액세스할 수 있습니다.

NestJS 미들웨어는 기본적으로 Express 미들웨어와 동일합니다. 다음과 같은 기능을 수행할 수 있습니다:

  • 코드 실행
  • 요청 및 응답 객체 변경
  • 요청-응답 주기 종료
  • 스택의 다음 미들웨어 함수 호출
  • 현재 미들웨어 함수가 요청-응답 주기를 종료하지 않으면 next()를 호출하여 다음 미들웨어 함수에 제어를 전달

의존성 주입

NestJS는 의존성 주입(DI) 디자인 패턴을 강력하게 활용합니다. 이를 통해 객체 간의 의존성을 줄이고, 코드를 더 모듈화하고 테스트하기 쉽게 만들 수 있습니다.

NestJS에서 의존성은 주로 생성자를 통해 주입됩니다. 프레임워크가 자동으로 의존성을 해결하고 필요한 인스턴스를 제공합니다.

예시:

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

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

데코레이터

제어권의 역전은 소프트웨어 아키텍쳐를 구성하는데에 있어, 하나의 “설계 원칙”이다.

개발자가 작성한 객체나 메서드의 제어를 개발자가 아니라 “외부에 위임”하는 설계원칙을 우린 “제어의 역전”이라 한다. 우린 “프레임워크”를 사용할 때 보통 이러한 경험을 많이 하게 된다. 우리가 코드를 일일이 작성하지 않음에도 불구하고 이미 그 기능을 외부로부터 받아와 구현할 수 있는 것이다.

"제어의 역전”을 통해 애플리케이션의 제어 책임이 프로그래머에서 프레임워크로 위임 되므로, 개발자는 핵심 비즈니스 로직에 조금 더 집중할 수 있게된다.

데코레이터는 클래스, 필드, 메소드에 대한 처리를 유연하게 돕는 기능입니다. 기능 추가, 변경, 접근 등의 처리에 대해 일일이 코드를 수정하는 대신 메타 정보를 입맛에 맞게 추가, 조합해서 구현 하려는 목적이 큽니다.


NestJS는 TypeScript의 데코레이터 기능을 광범위하게 사용합니다. 데코레이터는 클래스, 메서드, 속성에 메타데이터를 추가하고 동작을 변경하는 데 사용됩니다.

주요 데코레이터 예시: 이러한 기능에 추가적인 기능의 제어권을 프레임워크에 위임

  • @Module(): 모듈을 정의
  • @Controller(): 컨트롤러를 정의
  • @Injectable(): 프로바이더를 정의
  • @Get(), @Post(), @Put(), @Delete(): HTTP 메서드와 라우트를 정의
  • @Param(), @Body(), @Query(): 요청 매개변수를 추출

예외 처리

NestJS는 애플리케이션 전체에서 처리되지 않은 모든 예외를 처리하는 내장 예외 계층을 제공합니다. 예외가 애플리케이션 코드에서 처리되지 않으면, 이 계층에 의해 포착되고 적절한 사용자 친화적인 응답이 자동으로 전송됩니다.

내장 HttpException 클래스와 그 하위 클래스를 사용하여 HTTP 오류를 쉽게 던질 수 있습니다.

예시:

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

파이프

파이프는 @Injectable() 데코레이터로 주석이 달린 클래스입니다. 파이프는 두 가지 일반적인 사용 사례가 있습니다:

  1. 변환: 입력 데이터를 원하는 형식으로 변환 (예: 문자열에서 정수로)
  2. 유효성 검사: 입력 데이터를 평가하고 유효한 경우 변경하지 않고 전달, 그렇지 않으면 예외 throw

NestJS는 몇 가지 내장 파이프를 제공하며, 사용자 정의 파이프를 만들 수도 있습니다.

가드

가드는 @Injectable() 데코레이터로 주석이 달린 클래스입니다. 가드는 CanActivate 인터페이스를 구현해야 합니다. 가드의 책임은 런타임에 존재하는 특정 조건에 따라 주어진 요청이 라우트 핸들러에 의해 처리될지 여부를 결정하는 것입니다.

가드는 주로 인증과 권한 부여에 사용됩니다. 현재 요청과 관련된 조건(사용자 역할, 권한 등)에 따라 요청을 허용하거나 거부할 수 있습니다.

인터셉터

인터셉터는 @Injectable() 데코레이터로 주석이 달린 클래스입니다. 인터셉터는 NestInterceptor 인터페이스를 구현해야 합니다. 인터셉터는 다음과 같은 기능을 가집니다:

  • 메서드 실행 전/후에 추가 로직 바인딩
  • 함수에서 반환된 결과 변환
  • 함수에서 던져진 예외 변환
  • 기본 함수 동작 확장
  • 특정 조건에 따라 함수를 완전히 재정의

인터셉터는 요청과 응답을 가로채고 수정할 수 있어 로깅, 캐싱, 응답 변환 등에 유용합니다.

결론

NestJS는 강력하고 유연한 Node.js 프레임워크로, 확장 가능하고 유지보수가 용이한 서버 사이드 애플리케이션을 구축하는 데 이상적입니다. 모듈, 컨트롤러, 프로바이더와 같은 핵심 개념을 이해하고, 의존성 주입, 데코레이터, 파이프, 가드, 인터셉터 등의 고급 기능을 활용하면 강력한 엔터프라이즈급 애플리케이션을 개발할 수 있습니다.

NestJS의 아키텍처는 Angular에서 영감을 받았지만, Node.js 생태계의 모든 이점을 제공합니다. TypeScript를 기본으로 사용하여 타입 안정성을 제공하며, 기존 JavaScript 라이브러리와도 원활하게 통합됩니다.

이 프레임워크를 마스터하면 확장 가능하고 효율적이며 테스트하기 쉬운 백엔드 시스템을 구축할 수 있습니다. NestJS는 계속 발전하고 있으며, 활발한 커뮤니티 지원을 받고 있어 미래의 웹 개발에서 중요한 역할을 할 것으로 예상됩니다.

반응형