[NestJS] 기본 구조

soyeon·2023년 4월 10일

Nest

목록 보기
2/10
post-thumbnail

따라하면서 배우는 NestJS 를 따라가면서 간단하게 게시판 애플리케이션을 만들어보고자 한다.

예전에도 NestJS를 사용해봤지만 기초부터 차근차근 하면서 글로 정리할 것이다.

해당 프로젝트의 개요는 다음과 같다.

프로젝트 시작하기

  1. 프로젝트를 시작 할 폴더 생성
  2. 폴더 안에서 nest 기본 구조 생성
    nest new ./
    패키지 매니저 선택하기
  3. 앱 실행
    npm run start:dev
    에러 없이 실행이 되었다면 http://localhost:3000/ 으로 접속할 수 있다.
  4. NestJS 기본 구조 설명
  • eslintrc.js

    • 개발자들이 특정한 규칙을 가지고 코드를 깔끔하게 작성할 수 있도록 도와주는 라이브러리
    • 타입스크립트를 쓰는 가이드 라인 제시, 문법에 오류가 나면 알려주는 역할 등등
  • prettierrc

    • 주로 코드 형식을 맞추는데 사용(코드 포맷터)
  • nest-cli.json

    • nest 프로젝트를 위해 특정한 설정을 할 수 있는 파일
  • tsconfig.json

    • 어떻게 타입스크립트를 컴파일 할 지 설정
  • tsconfig.build.json

    • tsconfig.json의 연장선상 파일이며, build를 할 때 필요한 설정들 "excludes"에서는 빌드할 때 필요없는 파일들 명시
  • package.json

    • build: 운영환경을 위한 빌드
    • format: 린트에러가 났을 시 수정
    • start: 앱 시작
  • src 폴더

    • main.ts: 앱을 생성하고 실행
    • app.module.ts: 앱 모듈 정의

로직 흐름 살펴보기

  1. 앱을 생성하고 실행한다.
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule); 
  // AppModule에 등록된 정보를 통해 앱을 생성한다.
  await app.listen(3000);
  // 앱 실행
}
bootstrap();
  1. 클라이언트에서 http://localhost:3000/를 통해 get 요청을 보낸다.
  2. app.controller.ts 의 해당 endPoint의 Get 요청에 대한 로직을 실행한다.
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  
  @Get('/') 
  // http://localhost:3000/로 get 요청이 들어올때 실행되는 함수
  getHello(): string {
    return this.appService.getHello();
  }
}
  1. app.service.ts dml getHello() 실행
// app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!'; // Hello World! 를 반환
  }
}
  1. 파일 정리

흐름을 파악한 후 필요한 파일만 남기도록 파일을 정리해주자.

  • 파일 삭제하기
    app.controller.spec.ts
    app.controller.ts
    app.service.ts
    => 위의 파일 삭제

  • app.module.ts에서 삭제한 파일에 대한 에러 수정하기

// app.module.ts
import { Module } from '@nestjs/common';

@Module({
  imports: [],
})
export class AppModule {}
  • test 폴더 삭제

NestJS Module

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

각 애플리케이션에는 하나 이상의 모듈(루트 모듈)이 있으며 루트 모듈은 Nest가 사용하는 시작점이다.

모듈은 밀접하게 관련된 기능 집합으로 구성 요소를 구성하는 효과적인 방법이다. (ex. 유저 모듈, 주문 모듈, 챗 모듈...)

같은 기능에 해당하는 것들은 하나의 모듈 폴더 안에 넣어서 사용한다. (UserController, UserService, UserEntity 다 같은 기능이기에 UserModule 안에 넣는다.)

모듈은 기본적으로 싱글톤이므로 여러 모듈간에 쉽게 공급자의 동일한 인스턴스를 공유할 수 있다.

모듈 생성하기

nest g module boards

  • nest: nestcli를 사용하겠다.
  • g: generate 생성하겠다.
  • module: g 명령어를 통해 생성될 대상을 명시. 여기서는 module
  • boards: 대상의 이름

명령어를 사용하면 boards 폴더를 생성하고 그 안에 boards.module.ts 파일이 생성되고 이 생성된 파일을 app.module.ts에서 알 수 있도록 수정이 되었다.

이제부터 위에서 흐름을 파악한 것과 같이 로직을 작성해보면된다.

NestJS Controller

컨트롤러는 들어오는 요청을 처리하고 클라이언트에 응답을 반환한다.
@Controller() 데코레이터로 클래스를 정의하며 데코레이터의 인자로 들어오는 값이 Controller에 의해서 처리되는 "경로"다.

Hendller
@Get, @Post, @Delete 등과 같은 데코레이터로 장식된 컨트롤러 클래스 내의 단순한 메서드

컨트롤러 생성하기

nest g controller boards --no-spec

  • --no-spec: 기본적으로 controller를 테스트하는 파일을 생성해주지만 해당 명령어를 추가하면 생성하지 않는다는 뜻으로 boards.controller.ts 파일만 생성한다.

명령어를 사용하면 cli가 boards 폴더를 찾아서 안에 boards.controller.ts 파일을 생성한다.
boards 폴더 안에 module 파일을 찾아서 controller를 등록하도록 수정한다.

NestJS Service

컨트롤러에서 요청한 데이터 및 정보를 주기 위해 비즈니스 로직을 처리한다.

서비스 생성하기

nest g service boards --no-spec

@Injectable() 데코레이터를 통해 nestJS 프로젝트 내의 다른 컴포넌트에서 이 서비스를 사용할 수 있다.

사용하는 방법은 다음과 같이 controller에서 사용하는 예시를 통해 보자.

// boards.controller.ts
import { Controller } from '@nestjs/common';
import { BoardsService } from './boards.service';

@Controller('boards')
export class BoardsController {
  boardsService: BoardsService;
  // 3. typescript에서는 선언한 값만 객체의 프로퍼티로 사용할 수 있기때문에 위와 같이 선언
  
  constructor(boardsService: BoardsService) { // 1. BoardsService 타입 지정
  	this.boardsService = boardsService; 
    // 2. boardsService 를 BoardsController 클래스 내에서 사용하기 위해서 this.boardsService 에 할당
  }
  
  // 4. boardsService 라는 프로퍼티를 통해 BoardsService 사용 가능
  
}

위와 같은 코드는 TypeScript의 private와 같은 접근제한자를 사용하여 다음과 같이 작성할 수 있다.
private과 같이 생성자 안에서 사용할 경우 인수인 파라미터가 암묵적으로 클래스의 프로퍼티로 선언이 된다.

// boards.controller.ts
import { Controller } from '@nestjs/common';
import { BoardsService } from './boards.service';

@Controller('boards')
export class BoardsController {
  constructor(private boardsService: BoardsService) {}
}

NestJS Providers

프로바이더는 Nest의 기본 개념이며, 대부분의 기본 Nest 클래스는 서비스, 레포지토리, 팩토리, 헬퍼등 프로바이더로 취급할 수 있다.
프로바이더는 종속성을 주입할 수 있다.

위의 챕터에서와 같이 서비스를 컨트롤러에 주입한 것과 같다.

프로바이더 등록하기

provider를 사용하기 위해서는 module에 다음과 같이 등록이 되어있어야한다.

// boards.module.ts
import { Module } from '@nestjs/common';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';

@Module({
  controllers: [BoardsController],
  providers: [BoardsService], // 등록
})
export class BoardsModule {}
profile
사부작 사부작

0개의 댓글