본문 바로가기
TIL

Nest.js, TypeScript 프로젝트 mindo - 1 Hot( configModule or Service )

by 황민도 2024. 8. 21.

 

현 프로젝트는 Nest.js 와 TypeScript 를 활용하고

아래  API 명세서와 ERD 를 토대로 만든 프로젝트 이다.

아무것도 없이 시도하는 것이기 때문에 문제가 많을것을 참고해야한다.

 

 

https://shore-law-5df.notion.site/API-Plus-4e6645f8b51b4b409640583c42b5c208?pvs=4

 

API 명세서 ( Plus ) | Notion

공통

shore-law-5df.notion.site

sparta_node_ts | DrawSQL

 

sparta_node_ts | DrawSQL

Database schema diagram for sparta_node_ts.

drawsql.app

 

1. nest 디렉터리 생성, 깃 허브 연동

windo@DESKTOP-6SMB85M MINGW64 ~
$ nest new nestjs-mindo
⚡  We will scaffold your app in a few seconds..

? Which package manager would you ❤️  to use? (Use arrow keys)
? Which package manager would you ❤️  to use? npm
CREATE nestjs-mindo/.eslintrc.js (688 bytes)
CREATE nestjs-mindo/.prettierrc (54 bytes)
CREATE nestjs-mindo/nest-cli.json (179 bytes)
CREATE nestjs-mindo/package.json (2020 bytes)
CREATE nestjs-mindo/README.md (3413 bytes)
CREATE nestjs-mindo/tsconfig.build.json (101 bytes)
CREATE nestjs-mindo/tsconfig.json (567 bytes)
CREATE nestjs-mindo/src/app.controller.ts (286 bytes)
CREATE nestjs-mindo/src/app.module.ts (259 bytes)
CREATE nestjs-mindo/src/app.service.ts (150 bytes)
CREATE nestjs-mindo/src/main.ts (216 bytes)
CREATE nestjs-mindo/src/app.controller.spec.ts (639 bytes)
CREATE nestjs-mindo/test/jest-e2e.json (192 bytes)
CREATE nestjs-mindo/test/app.e2e-spec.ts (654 bytes)

- Installation in progress... ☕
√ Installation in progress... ☕

🚀  Successfully created project nestjs-mindo
👉  Get started with the following commands:

$ cd nestjs-mindo
$ npm run start


                          Thanks for installing Nest 🙏
                 Please consider donating to our open collective
                        to help us maintain this package.


                   🍷  Donate: https://opencollective.com/nest


windo@DESKTOP-6SMB85M MINGW64 ~
$ cd nestjs-mindo

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (master)
$ code .

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (master)
$ git add .
warning: in the working copy of '.gitignore', LF will be replaced by CRLF the next time Git touches it

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (master)
$ git commit -m "Start project"
[master (root-commit) c651f58] Start project
 16 files changed, 8919 insertions(+)
 create mode 100644 .eslintrc.js
 create mode 100644 .gitignore
 create mode 100644 .prettierrc
 create mode 100644 README.md
 create mode 100644 nest-cli.json
 create mode 100644 package-lock.json
 create mode 100644 package.json
 create mode 100644 src/app.controller.spec.ts
 create mode 100644 src/app.controller.ts
 create mode 100644 src/app.module.ts
 create mode 100644 src/app.service.ts
 create mode 100644 src/main.ts
 create mode 100644 test/app.e2e-spec.ts
 create mode 100644 test/jest-e2e.json
 create mode 100644 tsconfig.build.json
 create mode 100644 tsconfig.json

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (master)
$ git branch -M main

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ git remote add origin https://github.com/hwangmindo/Nestjs_mindo.git

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ git push -u origin main
Enumerating objects: 20, done.
Counting objects: 100% (20/20), done.
Delta compression using up to 20 threads
Compressing objects: 100% (20/20), done.
Writing objects: 100% (20/20), 82.64 KiB | 9.18 MiB/s, done.
Total 20 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/hwangmindo/Nestjs_mindo.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

 

2. 3계층 디렉터리 생성 및 git push

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ nest g res user
CREATE src/user/user.controller.ts (917 bytes)
CREATE src/user/user.controller.spec.ts (576 bytes)
CREATE src/user/user.module.ts (250 bytes)
CREATE src/user/user.service.ts (633 bytes)
CREATE src/user/user.service.spec.ts (464 bytes)
CREATE src/user/dto/create-user.dto.ts (31 bytes)
CREATE src/user/dto/update-user.dto.ts (173 bytes)
CREATE src/user/entities/user.entity.ts (22 bytes)
UPDATE package.json (2054 bytes)
UPDATE src/app.module.ts (318 bytes)
- Installing packages (npm)...
√ Packages installed successfully.

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ nest g res show
CREATE src/show/show.controller.ts (917 bytes)
CREATE src/show/show.controller.spec.ts (576 bytes)
CREATE src/show/show.module.ts (250 bytes)
CREATE src/show/show.service.ts (633 bytes)
CREATE src/show/show.service.spec.ts (464 bytes)
CREATE src/show/dto/create-show.dto.ts (31 bytes)
CREATE src/show/dto/update-show.dto.ts (173 bytes)
CREATE src/show/entities/show.entity.ts (22 bytes)
UPDATE src/app.module.ts (379 bytes)

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ nest g res book
CREATE src/book/book.controller.ts (917 bytes)
CREATE src/book/book.controller.spec.ts (576 bytes)
CREATE src/book/book.module.ts (250 bytes)
CREATE src/book/book.service.ts (633 bytes)
CREATE src/book/book.service.spec.ts (464 bytes)
CREATE src/book/dto/create-book.dto.ts (31 bytes)
CREATE src/book/dto/update-book.dto.ts (173 bytes)
CREATE src/book/entities/book.entity.ts (22 bytes)
UPDATE src/app.module.ts (440 bytes)

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ nest g res auth
CREATE src/auth/auth.controller.ts (917 bytes)
CREATE src/auth/auth.controller.spec.ts (576 bytes)
CREATE src/auth/auth.module.ts (250 bytes)
CREATE src/auth/auth.service.ts (633 bytes)
CREATE src/auth/auth.service.spec.ts (464 bytes)
CREATE src/auth/dto/create-auth.dto.ts (31 bytes)
CREATE src/auth/dto/update-auth.dto.ts (173 bytes)
CREATE src/auth/entities/auth.entity.ts (22 bytes)
UPDATE src/app.module.ts (501 bytes)

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ git add .
warning: in the working copy of 'src/app.module.ts', LF will be replaced by CRLF the next time Git touches it

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ git commit -m "Setup project structure"
[main 9c73668] Setup project structure
 35 files changed, 478 insertions(+), 1 deletion(-)
 create mode 100644 src/auth/auth.controller.spec.ts
 create mode 100644 src/auth/auth.controller.ts
 create mode 100644 src/auth/auth.module.ts
 create mode 100644 src/auth/auth.service.spec.ts
 create mode 100644 src/auth/auth.service.ts
 create mode 100644 src/auth/dto/create-auth.dto.ts
 create mode 100644 src/auth/dto/update-auth.dto.ts
 create mode 100644 src/auth/entities/auth.entity.ts
 create mode 100644 src/book/book.controller.spec.ts
 create mode 100644 src/book/book.controller.ts
 create mode 100644 src/book/book.module.ts
 create mode 100644 src/book/book.service.spec.ts
 create mode 100644 src/book/book.service.ts
 create mode 100644 src/book/dto/create-book.dto.ts
 create mode 100644 src/book/dto/update-book.dto.ts
 create mode 100644 src/book/entities/book.entity.ts
 create mode 100644 src/show/dto/create-show.dto.ts
 create mode 100644 src/show/dto/update-show.dto.ts
 create mode 100644 src/show/entities/show.entity.ts
 create mode 100644 src/show/show.controller.spec.ts
 create mode 100644 src/show/show.controller.ts
 create mode 100644 src/show/show.module.ts
 create mode 100644 src/show/show.service.spec.ts
 create mode 100644 src/show/show.service.ts
 create mode 100644 src/user/dto/create-user.dto.ts
 create mode 100644 src/user/dto/update-user.dto.ts
 create mode 100644 src/user/entities/user.entity.ts
 create mode 100644 src/user/user.controller.spec.ts
 create mode 100644 src/user/user.controller.ts
 create mode 100644 src/user/user.module.ts
 create mode 100644 src/user/user.service.spec.ts
 create mode 100644 src/user/user.service.ts

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ git push origin main
Enumerating objects: 55, done.
Counting objects: 100% (55/55), done.
Delta compression using up to 20 threads
Compressing objects: 100% (38/38), done.
Writing objects: 100% (50/50), 6.33 KiB | 1.58 MiB/s, done.
Total 50 (delta 19), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (19/19), completed with 3 local objects.
To https://github.com/hwangmindo/Nestjs_mindo.git
   c651f58..9c73668  main -> main

 

3. DB 연결

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ npm i --save @nestjs/typeorm typeorm mysql2

added 35 packages, and audited 739 packages in 10s

114 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

typeorm 을 사용하여 DB 를 연결하기 위해 위 명령어를 입력

 

 

< src. app.module.ts >

@Module({
  imports: [TypeOrmModule.forRoot({
    type: 'mysql',
    host: 'DB 엔드포인트 주소 or localhost',
    port: 3306,
    username: 'root'
    password: '12345678'
    database: 'mindo',
    entities: [],
    synchronize: true
  }),UserModule, ShowModule, BookModule, AuthModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

DB 설정틀을 공식문서를 참고하여 작성해준 뒤 .env 와 joi 검증을 위한 TypeOrmconfigschema 객체 생성하기

mySql 이 localhost 에 설치한 DB 일시: localhost

인터넷에서만 활용되는 엔드포인트 DB 일시: DB 엔드포인트 주소

(ex: express-database.aaaaaaaaa0aa.ap-northeast-2.rds.amazonaws.com)

 

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ npm i joi

added 6 packages, and audited 745 packages in 1s

114 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

joi 설치 명령어

 

 

< src.config. type-orm.schema.ts >

import Joi from 'joi';

export const typeOrmConfigSchema = Joi.object({
  type: Joi.string().default('mysql'),
  host: Joi.string().default('localhost'),
  port: Joi.number().default('3306'),
  username: Joi.string().required(),
  password: Joi.string().required(),
  database: Joi.string().required(),
  entities: Joi.array().items(Joi.string()).optional(),
  synchronize: Joi.boolean().required(),
});

일단 joi 로 스키마를 설정해준다.

 

 

< .env >

DB_TYPE = 'mysql'
DB_HOST = 'localhost'
DB_PORT = '3306'
DB_USERNAME = 'root'
DB_PASSWORD = '12345678'
DB_NAME = 'mindo'
DB_SYNC = true

위의 .env 를 환경변수로 사용하려면 configService를 이용해야 한다. 

Configuration | NestJS - A progressive Node.js framework

 

 

windo@DESKTOP-6SMB85M MINGW64 ~/nestjs-mindo (main)
$ npm i --save @nestjs/config

added 2 packages, and audited 747 packages in 2s

114 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

config 를 설치해주고

 

< src.config. type-orm.config.ts>

import { ConfigModule, ConfigService } from '@nestjs/config';

export const typeOrmConfig = {
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (configService: ConfigService) => ({
    type: configService.get('DB_TYPE'),
    host: configService.get('DB_HOST'),
    port: configService.get('DB_PORT'),
    username: configService.get('DB_USERNAME'),
    password: configService.get('DB_PASSWORD'),
    database: configService.get('DB_NAME'),
    entities: [],
    synchronize: configService.get('DB_SYNC'),
  }),
};
TypeOrmModule.forRootAsync(typeOrmConfig)

위 메서드에 유연하게 가져다 쓰기 위해 클래스가 아닌 객체를 생성하여

useFactory  를 사용해 configSevice 를 가져다 쓸수 있도록 하였다.

 

이렇게 하면 아래와같이 app.module.ts 가 정리된다.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { ShowModule } from './show/show.module';
import { BookModule } from './book/book.module';
import { AuthModule } from './auth/auth.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
import { typeOrmConfigSchema } from './config/type-orm.schema';
import { typeOrmConfig } from './config/type-orm.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validationSchema: typeOrmConfigSchema,
    }),
    TypeOrmModule.forRootAsync(typeOrmConfig),
    UserModule,
    ShowModule,
    BookModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

이렇게 해서 데이터베이스 연결은 validationSchema: typeOrmConfigSchema (joi로 validation) 로 환경변수를 검증하도록 하였고 configService를 사용하여 환경변수를 불러오기 전 위 joi로 자동 검증이 된다.

이런 이점도 있지만 굳이 configMoudle을 사용하여 configService를 사용하는 이유는 아래 공식 문서를 참고하는게 좋다.

Configuration | NestJS - A progressive Node.js framework 

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});

위와 같이  env 파일을 다르게 작명하고 여러개를 만들어도 위와같이 설정하여 env 환경변수를 좀더 유연하게 검증하고 불러와 사용할수 있다. 이것은 process.env 를 사용하는 것 보다 훨씬 더 많은 장점을 가지고 있다.