scratch에서 시작한다.

Nest 기초

시작 및 설치하기

npm init -y 로 package.json 생성한다.

그 후 종속성 5개를 설치한다.

  • "@nestjs/common": "^7.6.17" : Nest에서 함수, 클래스 등 대다수를 가져온다.

"@nestjs/core": "^7.6.17"

"@nestjs/platform-express": "^7.6.17" : HTTP 요청을 다루기 위해 Nest가 ExpressJS 사용하도록 해준다.

"reflect-metadata": "^0.1.13" : decorator

"typescript": "^4.3.2" : 사용할 언어

TS(Typescript) 컴파일러 세팅

루트 디렉토리에 다음과 같이 tsconfig.json 파일을 만든다.

1
2
3
4
5
6
7
8
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es2017",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
    }
}

HTTP 요청과 응답 사이에 서버에서 발생하는 일

  1. 요청 (in Nest)

  2. 요청의 body에 담긴 데이터 타당성 검사(Pipe)

  3. 유저의 권한 확인(Guard)

  4. 함수로 연결(Controller)

  5. 연결된 함수에서 business logic 실행(Service)

  6. 데이터베이스 접근(Repository)

  7. 응답

Nest의 구성

  • Controllers : 요청 처리
  • Services : 데이터 접근과 비즈니스 로직 처리
  • Modules : 코드 묶기
  • Pipes : 받은 데이터의 타당성 검사
  • Filters : 요청 처리 중 발생한 에러 처리
  • Guards : 권한 확인
  • Interceptors : 받은 요청이나 내보내는 응답에 추가 로직 부여
  • Repostiroies : DB에 저장된 데이터 처리

Nest module과 controller 만들기

루트디렉토리에 src 폴더를 만들고 안에 main.ts 파일을 만든다.

보통 모듈과 컨트롤러 자체의 디렉토리를 만들지만 이번엔 main.ts에 포함시킬 것.

main.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { Controller, Module, Get } from '@nestjs/common'; // 일반적으로 core보단 common에서 import할 때가 훨씬 많다.
import { NestFactory } from '@nestjs/core';

@Controller() // Nest에게 클래스를 만들고 컨트롤러로 사용할 것이라고 말하는 decorator
class AppController {
  @Get() // 루트 처리하는 decorator
  getRootRoute() {
    return 'hi there!';
  }
}

@Module({
  // 모듈 decorator에는 구성옵션이나 개체 전달
  controllers: [AppController],
})
class AppModule {}

async function bootstrap() {
  const app = await NestFactory.create(AppModule); // 애플리케이션의 인스턴스 생성

  await app.listen(3000); // 들어오는 트래픽 수식
}

bootstrap();

npx ts-node-dev src/main.ts를 터미널에 입력해서 실행해보

[INFO] 14:31:26 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 5.2.2) [Nest] 3320 - 2023. 10. 05. 오후 2:31:31 [NestFactory] Starting Nest application… [Nest] 3320 - 2023. 10. 05. 오후 2:31:31 [InstanceLoader] AppModule dependencies initialized +53ms [Nest] 3320 - 2023. 10. 05. 오후 2:31:31 [RoutesResolver] AppController {}: +19ms [Nest] 3320 - 2023. 10. 05. 오후 2:31:31 [RouterExplorer] Mapped {, GET} route +6ms [Nest] 3320 - 2023. 10. 05. 오후 2:31:31 [NestApplication] Nest application successfully started +6ms

라고 뜨면서 서버가 잘 실행된다.

링크 접속해봐도 hi there!라고 잘뜬다.

컨트롤러, 모듈 추출하기

명명법

  1. class AppController {} : 컨트롤러라는 type의 클래스. 이름은 App이다. 따라서 app.controller.ts
  2. class AppModule {} : 모듈이라는 type의 클래스. 이름은 App이다. 따라서 app.module.ts

위와 같은 방식으로 파일 이름으로 이해할 수 있도록 명명해야 한다.

이제 Appcontroller, Appmodule을 옮기고 import 도 적절하게 바꿔준 후 해당 클래스를 export 처리한다.

1
2
3
4
5
6
7
8
9
10
11
//main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule); // 애플리케이션의 인스턴스 생성

  await app.listen(3000); // 들어오는 트래픽 수식
}

bootstrap();
1
2
3
4
5
6
7
8
9
10
11
//app.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
  // 다른 파일에서 이 클래스 접근할 수 있도록 export로 설정
  @Get()
  getRootRoute() {
    return 'hi there!';
  }
}
1
2
3
4
5
6
7
8
//app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  controllers: [AppController],
})
export class AppModule {} // export 추가하기

npx ts-node-dev src/main.ts를 터미널에서 실행해보면 링크가 여전히 잘 실행된다!

Routing Decorators

컨트롤러 클래스에서 @get() decorator에 ‘/asdf’ 를 인자로 넣어주면 링크 에 오류가 뜬다.

1
2
3
4
5
6
7
8
9
import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
  @Get('/asdf')
  getRootRoute() {
    return 'hi there!';
  }
}

xxxxxxxxxx1 1{“statusCode”:404,”message”:”Cannot GET /”,”error”:”Not Found”} 라는 오류가 뜬다.

대신 /asdf를 추가한 링크 로 가면 이전처럼 ‘hi there!’이 잘뜬다.

@Controller decorator에도 적용할 수 있다. ‘/app’을 추가하여 새로운 링크 로 들어가야하면 ‘hi there!’를 만날 수 있다.

AppController에 또다른 라우터 함수를 추가해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// app.controller.ts
import { Controller, Get } from '@nestjs/common';

@Controller('/app')
export class AppController {
  @Get('/asdf')
  getRootRoute() {
    return 'hi there!';
  }

  @Get('/bye')
  getByeThere() {
    return '잘가유!';
  }
}

들어가서 잘되나 보자,

서버가 켜져있는지 꼭 확인할 것!