4. Database
1. 데이터베이스 생성하기
Postgres를 설치한 후 board-app
이라는 데이터베이스를 생성한다.
2. TypeORM 관련 모듈 설치하기
TypeORM은 NodeJS에서 실행되고 TypeScript로 작성된 객체 관계형 매퍼 라이브러리이며, 다양한 데이터베이스 관리 시스템을 지원한다.
다음과 같이 관련 모듈을 설치한다.
3. TypeORM 애플리케이션에 연결하기
먼저 TypeORM을 애플리케이션에 연결하기 위한 설정 파일을 생성하기 위해 src
디렉터리에 configs
디렉터리를 생성한다.
다음과 같이 설정 파일을 작성하면 되는데, entities
프로퍼티의 경우 엔터티를 직접 입력해도 되지만, autoLoadEntities: true
로 지정한 경우 생략할 수 있다.
import { TypeOrmModuleOptions } from "@nestjs/typeorm";
export const typeOrmConfig: TypeOrmModuleOptions = {
type: "postgres",
host: "localhost",
port: 5432,
username: "postgres",
password: "postgres",
database: "board-app",
autoLoadEntities: true,
// entities: [Entity1, Entity2, ...],
synchronize: true,
};
이렇게 구성한 설정 파일을 모든 모듈에서 사용할 수 있도록 루트 모듈의 imports
배열에 넣어준다.
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { BoardsModule } from "./boards/boards.module";
import { typeOrmConfig } from "./configs/typeorm.config";
@Module({
imports: [TypeOrmModule.forRoot(typeOrmConfig), BoardsModule],
})
export class AppModule {}
4. 게시물을 위한 엔터티 생성하기
엔터티를 생성해서 사용하면 데이터베이스 관련 작업을 편리하게 할 수 있다.
다음과 같이 게시물을 위한 Board
엔터티를 생성해 보자.
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { BoardStatus } from "./board.model";
@Entity()
export class Board {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
description: string;
@Column()
status: BoardStatus;
}
5. 모듈에 엔터티 등록하기
데이터베이스 관련 작업은 리포지터로 처리하는데, 엔터티를 관리하는 것이라고 생각하면 된다.
먼저 엔터티를 사용하기 위해 Boards
모듈의 imports
배열에 Board
엔터티를 넣어준다.
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Board } from "./board.entity";
import { BoardsController } from "./boards.controller";
import { BoardsService } from "./boards.service";
@Module({
imports: [TypeOrmModule.forFeature([Board])],
controllers: [BoardsController],
providers: [BoardsService],
})
export class BoardsModule {}
이제 BoardsService
의 constructor
에 리포지터리 boardRepository
를 주입하여 생성할 것이다. 먼저 불필요한 코드 및 파일은 정리하기 위해 board.model.ts
의 Board
인터페이스를 지우고 board-status.enum.ts
파일명으로 변경한 후 종속되는 경로 및 코드를 모두 수정해 준다.
import { BadRequestException, PipeTransform } from "@nestjs/common";
import { BoardStatus } from "../board-status.enum";
export class BoardStatusValidationPipe implements PipeTransform {
readonly StatusOptions = [BoardStatus.PUBLIC, BoardStatus.PRIVATE];
private isStatusValid(status: any): boolean {
return this.StatusOptions.includes(status);
}
transform(value: any) {
value = value.toUpperCase();
if (!this.isStatusValid(value)) {
throw new BadRequestException(`${value} isn't in the status`);
}
return value;
}
}
import {
Body,
Controller,
Delete,
Get,
Param,
Patch,
Post,
UsePipes,
ValidationPipe,
} from "@nestjs/common";
import { BoardStatus } from "./board-status.enum";
import { BoardsService } from "./boards.service";
import { CreateBoardDto } from "./dto/create-board.dto";
import { BoardStatusValidationPipe } from "./pipes/board-status-validation.pipe";
@Controller("boards")
export class BoardsController {
constructor(private boardsService: BoardsService) {}
}
6. 리포지터리 주입하기
Board
엔터티를 관리하는 리포지터리를 사용하려면 다음과 같이 BoardsService
의 constructor
안에 @InjectRepository
데코레이터를 달아준 후 선언하면 된다.
import { Injectable, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { BoardStatus } from "./board-status.enum";
import { Board } from "./board.entity";
import { CreateBoardDto } from "./dto/create-board.dto";
@Injectable()
export class BoardsService {
constructor(
@InjectRepository(Board) private boardRepository: Repository<Board>
) {}
}