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 요청과 응답 사이에 서버에서 발생하는 일
-
요청 (in Nest)
-
요청의 body에 담긴 데이터 타당성 검사(Pipe)
-
유저의 권한 확인(Guard)
-
함수로 연결(Controller)
-
연결된 함수에서 business logic 실행(Service)
-
데이터베이스 접근(Repository)
-
응답
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!라고 잘뜬다.
컨트롤러, 모듈 추출하기
명명법
- class AppController {} : 컨트롤러라는 type의 클래스. 이름은 App이다. 따라서
app.controller.ts
- 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 '잘가유!';
}
}
서버가 켜져있는지 꼭 확인할 것!