낙서장이자 오답 노트이자 컨닝 페이퍼
패스트캠퍼스 환급챌린지 11일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기 본문
패스트캠퍼스 환급챌린지 11일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기
NangIn 2025. 4. 11. 20:27본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
강의 내용 정리
TypeORM 기본기 DataSource와 Column
TypeORM이란?
- TypeScript 기반 ORM(Object Relational Mapping)
- 복잡한 SQL 없이도 데이터베이스 조작을 객체지향적으로 할 수 있도록 도와줌
- SQL을 직접 작성하지 않고도, 클래스 기반 정의로 DB 테이블 생성 및 조작 가능
주요 특징
| 항목 | 설명 |
| 🏷️ Entity 기반 | 클래스 → 테이블, 필드 → 칼럼으로 자동 매핑 |
| 🛠️ DB 종류 지원 | PostgreSQL, MySQL, SQLite 등 다양한 DB 지원 |
| 🔁 마이그레이션 기능 | DB 구조 변경 이력 관리 가능 |
| 🔗 관계 설정 | 테이블 간 관계(1:1, 1:N, N:M) 정의 가능 |
| 📌 로딩 전략 | eager/lazy loading 지원 (필요한 시점에 관계 데이터 조회) |
| 🔐 안전성 | 타입 기반 + 제약 조건으로 DB 무결성 강화 |
핵심 구성 요소
- DataSource → 사용할 데이터베이스 지정 및 정보 제공역할
-
export const AppDataSource = new DataSource({ type: 'postgres', host: 'localhost', port: 5432, username: 'postgres', password: 'postgres', database: 'myapp', entities: [Movie], synchronize: true, });- type, host, port 등 DB 연결 정보
- entities: 연결할 엔티티(테이블)
- synchronize: true로 설정 시, 코드 기반으로 자동 테이블 생성
-
- @Entity (클래스 → 테이블)
-
@Entity() export class Movie { @PrimaryGeneratedColumn() id: number; @Column() title: string; @Column() genre: string; } -
데코레이터 역할 @Entity() 클래스가 DB 테이블이라는 선언 @PrimaryGeneratedColumn() 기본 키 & 자동 증가 칼럼 생성 @Column() 일반 칼럼 생성
-
Column 옵션 예시
- Column 옵션은 첫번째 파라미터에 객체로 제공
-
옵션 설명 type: ColumnType varchar, text, int 등 SQL 타입 명시 (보통 생략 가능) name: string 데이터베이스에 저장될 칼럼이름. 기본값은 프로퍼티 이름을 따름 nullable: boolean null 허용 여부. 기본값 false default: string 기본값 설정 unique: boolean 유일값 제약 조건. 기본값 false select: boolean 쿼리 실행시 프로퍼티를 가져올지 결정. false일 경우 가져오지 않는게 기본 update: boolean 수정 불가 필드 설정 가능. 기본값 true comment: string 칼럼 코멘트. 모든 데이터베이스에서 지원되진 않음 enum: string[] 칼럼에 입력 가능한 값을 enum으로 나열 array: boolean 칼럼 array 타입으로 생성. 예) int[]
특수 칼럼 (자동 생성/관리 필드)
| 데코레이터 | 설명 |
| @CreateDateColumn() | 생성 시 자동 시간 저장 |
| @UpdateDateColumn() | 수정 시 자동 시간 저장 |
| @DeleteDateColumn() | 소프트 삭제 시 시간 저장 |
| @VersionColumn() | 변경 이력 관리 (수정마다 1씩 증가) |
마무리 요약
- TypeORM은 SQL을 몰라도 데이터베이스 설계/조작 가능
- 클래스와 데코레이터만으로 테이블, 칼럼, 제약 조건 설정
- NestJS와 강력하게 통합되어 실무에서 널리 사용됨
- SQL을 아는 상태에서 사용하면 이해도 및 활용도 배가됨
DataSource 정의하고 환경변수 사용해보기
필요한 패키지 설치
pnpm add @nestjs/config joi @nestjs/typeorm typeorm pg
| 패키지 | 설명 |
| @nestjs/config | 환경변수 관리용 |
| joi | 환경변수 유효성 검사 |
| @nestjs/typeorm | NestJS용 TypeORM 모듈 |
| typeorm | TypeORM ORM 라이브러리 |
| pg | PostgreSQL 드라이버 |
데이터베이스 연결 설정
- app.module.ts에서 TypeORM 설정:
- 연결하고 싶은 DB의 정보 넣어줌
import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: 'localhost', port: 5555, username: 'postgres', password: 'postgres', database: 'postgres', entities: [], synchronize: true, }), ], }) export class AppModule {}- synchronize: true → 코드 변경 시 DB 구조도 자동 반영 (개발환경 전용)
- 운영 환경에서는 위험하므로 반드시 false로 설정하고, 대신 마이그레이션 사용
환경변수로 설정값 관리
- .env 파일 생성 (프로젝트 루트에 위치):
-
DB_TYPE=postgres DB_HOST=localhost DB_PORT=5555 DB_USERNAME=postgres DB_PASSWORD=postgres DB_DATABASE=postgres ENV=dev
-
- @nestjs/config 모듈 등록:
- process.env.VARIABLE_NAME 으로 접근 가능
-
import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot(), TypeOrmModule.forRoot({ type: process.env.DB_TYPE as "postgres", host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, entities: [], synchronize: true, }), ], })
연결 확인 및 디버깅 팁
- 연결 정보가 잘못되면 NestJS 실행 시 에러 출력됨
- 예: 비밀번호 틀리면 password authentication failed 등
- 하나씩 설정을 바꾸며 에러 확인해보는 것도 좋은 학습
Joi로 환경변수 검증하고 비동기로 DataSource 생성하기
왜 Joi로 검증해야 할까?
- .env 파일에 오타, 누락, 잘못된 타입이 들어가도 기본적으로 에러가 안 남.
- Joi로 미리 스키마를 정의하고 검증하면, 실행 전 오류를 막을 수 있음.
- 특히 프로덕션 환경에서 DB 연결 등 치명적인 문제를 예방할 수 있음.
설치된 패키지
pnpm add @nestjs/config joi
.env 파일 예시
DB_TYPE=postgres
DB_HOST=localhost
DB_PORT=5555
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE=postgres
ENV=dev
ConfigModule에 Joi 스키마 적용
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
ConfigModule.forRoot({
isGlobal: true,
validationSchema: Joi.object({
DB_TYPE: Joi.string().valid('postgres').required(),
DB_HOST: Joi.string().required(),
DB_PORT: Joi.number().required(),
DB_USERNAME: Joi.string().required(),
DB_PASSWORD: Joi.string().required(),
DB_DATABASE: Joi.string().required(),
ENV: Joi.string().valid('dev', 'prod').required(),
}),
}),
- isGlobal: true 옵션은 모든 모듈에서 환경변수를 자동으로 접근할 수 있게 함.
TypeOrmModule.forRootAsync()로 설정 동적 주입
- ConfigModule이 인스턴스화가 된 다음 주입 받아야 하기 때문에 비동기
- useFactory를 사용하면 컨트롤러처럼 IOC 컨테이너에서 의존성 주입을 받을 수 있음 (configService) → inject 파라미터에 의존성 주입 받을 인스턴스를 넣어줘야 함
-
import { TypeOrmModule } from '@nestjs/typeorm'; import { ConfigService } from '@nestjs/config'; TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: (configService: ConfigService) => ({ type: configService.get<'postgres'>('DB_TYPE'), host: configService.get<string>('DB_HOST'), port: configService.get<number>('DB_PORT'), username: configService.get<string>('DB_USERNAME'), password: configService.get<string>('DB_PASSWORD'), database: configService.get<string>('DB_DATABASE'), entities: [], // 엔티티 추가 예정 synchronize: true, }), }),
Joi 검증이 실패하면?
- 환경변수 누락 or 오타 → NestJS 실행 시 즉시 에러 발생
-
Error: Config validation error: "DB_DATABASE" is required
장점
- 실행 전 환경변수 오류 사전 차단
- 설정 실수로 DB나 API 오작동 방지
- → 실무에서도 Joi + ConfigService 조합은 사실상 필수
학습 후기
TypeORM의 기본 개념과 환경변수 연동까지 배우면서 ORM이 단순히 SQL을 대체하는 도구가 아니라, 객체지향적인 데이터 설계와 유지보수성을 동시에 잡을 수 있는 강력한 도구라는 점을 다시 느꼈습니다. @Entity, @Column 같은 데코레이터 기반의 구조는 NestJS의 모듈 아키텍처와도 자연스럽게 어우러져, 처음에는 복잡하게 느껴졌던 DB 연동이 오히려 더 명확하고 일관된 방식으로 다가왔습니다. 특히 특수 칼럼을 통한 자동 생성 필드는 일일이 관리하지 않아도 되니 실무에서 매우 유용할 것이라 생각했습니다.
환경변수를 다룰 때 Joi를 통해 스키마를 정의하고, 이를 기반으로 .env 값을 검증하는 방식은 매우 인상 깊었습니다. 이전에는 단순히 .env 파일을 만들어두고 불러오기만 했던 저에게, Joi를 활용한 사전 검증은 일종의 안전장치처럼 느껴졌습니다. 특히 실무에서는 실수로 한 글자만 잘못 써도 서버가 오작동할 수 있는데, Joi 덕분에 이런 실수를 사전에 방지할 수 있는 점이 마음에 들었습니다. TypeORM의 연결 설정을 비동기 방식으로 구성하는 forRootAsync 패턴도 NestJS답게 의존성 주입 컨셉을 그대로 적용할 수 있어서 구조적으로 깔끔했습니다.
전체적으로 이번 학습은 NestJS와 TypeORM, 그리고 환경변수 설정 및 검증까지 하나의 흐름으로 이해할 수 있었던 시간이었습니다. 각각을 따로따로 배웠다면 연결이 어려웠을 부분인데, 실제 프로젝트 구조 안에서 연동하며 학습하니 모든 개념이 유기적으로 맞물린다는 점을 체감했습니다. 앞으로 DB 설계나 배포 환경 전환 작업이 있을 때도 훨씬 자신감 있게 접근할 수 있을 것 같습니다.
학습 인증샷



