Postgres & TypeORM 연동
설치할 두가지
1. PostgresSQL
2. pgAdmin (데이터베이스를 보는 툴(Tool)입니
다.)
Window 에서 PostgresSQL 설치하기
이 사이트 가서 인스톨러 다운로드
https://www.postgresql.org/download/windows/
Mac 에서 PostgresSQL 설치하기 이 사이트 가서 인스톨러 다운로드
https://postgresapp.com/downloads.html
Window & Mac 에서 pgAdmin 설치하기 이 사이트 가서 인스톨러 다운로드
https://www.pgadmin.org/download/
board-app db 생성
TypeORM 소개
TypeORM 이용
npm install pg typeorm @nestjs/typeorm --save
typeorm.config.ts
import { TypeOrmModuleOptions } from "@nestjs/typeorm";
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'board-app',
entities: [__dirname + '/../**/*.entity.{js,ts'],
synchronize: true
}
app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardsModule } from './boards/boards.module';
import { typeORMConfig } from './boards/configs/typeorm.config';
@Module({
imports: [TypeOrmModule.forRoot(typeORMConfig),
BoardsModule],
controllers: [],
providers: [],
})
export class AppModule {}
board.entity.ts
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { BoardStatus } from "./boards/board-status.enum";
@Entity()
export class Board extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
description: string;
@Column()
status: BoardStatus;
}
board.repository.ts
import { EntityRepository, Repository } from "typeorm";
import { Board } from "./board.entity";
@EntityRepository(Board)
export class BoardRepository extends Repository<Board> {
}
board.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardRepository } from 'src/board.repository';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
@Module({
imports: [
TypeOrmModule.forFeature([BoardRepository])
],
...
})
export class BoardsModule {}
데이터베이스를 이용한 CRUD 구현
ID를 이용해서 특정 게시물 가져오기
게시물 생성하기
게시물 삭제하기
board.repository.ts
import { EntityRepository, Repository } from "typeorm";
import { BoardStatus } from "./board-status.enum";
import { Board } from "./board.entity";
import { CreateBoardDto } from "./dto/create-board.dto";
@EntityRepository(Board)
export class BoardRepository extends Repository<Board> {
async createBoard(createBoardDto: CreateBoardDto): Promise<Board> {
const {title, description} = createBoardDto;
const board = this.create({
title,
description,
status: BoardStatus.PUBLIC
})
await this.save(board);
return board;
}
}
board.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { NotFoundError } from 'rxjs';
import { Board } from 'src/boards/board.entity';
import { BoardStatus } from './board-status.enum';
import { BoardRepository } from './board.repository';
import { CreateBoardDto } from './dto/create-board.dto';
@Injectable()
export class BoardsService {
constructor(
@InjectRepository(BoardRepository)
private boardRepository: BoardRepository
){}
async getAllBoards(): Promise <Board[]> {
return this.boardRepository.find();
}
createBoard(createBoardDto: CreateBoardDto): Promise<Board> {
return this.boardRepository.createBoard(createBoardDto);
}
async getBoardById(id: number): Promise<Board> {
const found = await this.boardRepository.findOne(id);
if (!found) {
throw new NotFoundException(`Can't find the board with id ${id}`);
}
return found;
}
async deleteBoard(id: number): Promise<void> {
const result = await this.boardRepository.delete(id);
if (result.affected === 0) {
throw new NotFoundException(`Can't find Board with id ${id}`);
}
}
async updateBoardStatus(id: number, status: BoardStatus): Promise<Board> {
const board = await this.getBoardById(id);
board.status = status;
await this.boardRepository.save(board);
return board;
}
}
board.controller.ts
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UsePipes, ValidationPipe } from '@nestjs/common';
import { BoardStatus } from './board-status.enum';
import { Board } from './board.entity';
import { BoardsService } from './boards.service';
import { CreateBoardDto } from './dto/create-board.dto';
import { BoardStatusValidationPipe } from './pipes/board-status-validation.pipes';
@Controller('boards')
export class BoardsController {
constructor(private boardsService: BoardsService) {}
@Get('/')
getAllBoard(): Promise<Board[]> {
return this.boardsService.getAllBoards();
}
@Post()
@UsePipes(ValidationPipe)
createBoard(@Body() CreateBoardDto: CreateBoardDto): Promise<Board> {
return this.boardsService.createBoard(CreateBoardDto);
}
@Get('/:id')
getBoardById(@Param('id') id: number): Promise<Board> {
return this.boardsService.getBoardById(id);
}
@Delete('/:id')
deleteBoard(@Param('id', ParseIntPipe) id): Promise<void> {
return this.boardsService.deleteBoard(id);
}
@Patch('/:id/status')
updateBoardStatus(
@Param('id', ParseIntPipe) id: number,
@Body('status', BoardStatusValidationPipe) status: BoardStatus
) {
return this.boardsService.updateBoardStatus(id, status);
}
}
ParseIntPipe는 숫자만 들어오도록 만들어진 파이프다.
모듈 구조가 중요하다. 첨에 실습했을 때 Board의 Metadata를 못찾는다는 에러가 나왔는데, typeorm.config.ts에 엔티티의 위치가 상대경로로 들어가있어서 그런듯하다.
'nestjs' 카테고리의 다른 글
[NestJS] 인프런 -따라하며 배우는 NestJS 3 (0) | 2022.08.11 |
---|---|
[Nest.js, TypeORM] Relation이 된 entity를 받을 수 없었다. (0) | 2022.08.11 |
[Nest.js, TypeORM] RepositoryNotFoundError (0) | 2022.08.11 |
[TypeORM, Nest.js] ManyToOne 관계의 entity가 null return 될 때 (0) | 2022.08.11 |
[NestJS] TypeORM — Relation, Transactions (0) | 2022.08.11 |