NestJS에서 Repository 패턴을 구현하는 방법을 알아봅니다.
강의에 따라 학습하던 중 controller-service-repository 패턴을 구성하는데 repository 부분에서 @EntityRepository()
데코레이터를 사용했는데, deprecated 메시지가 떴습니다.
GPT가 답변해준 @InjectRepository()
데코레이터도 안먹혔습니다.
NestJS에서 기본적으로 생성해주는 CRUD App은 module-controller-service 구조입니다.
service에서 비즈니스 로직을 처리하고 DB에 접근하는 작업은 repository에서 처리하도록 Repository 패턴을 구현해봅니다.
게시판 앱을 예로 만들어보겠습니다.
nest g res 명령어로 생성한 코드를 기본으로 시작해보겠습니다.
필요한 파일
설치가 필요한 모듈
boards.controller.ts
import { Controller, Post } from '@nestjs/common';
import { BoardsService } from './boards.service';
import { CreateBoardDto } from './dto/create-board.dto';
@Controller('boards')
export class BoardsController {
constructor(private readonly boardsService: BoardsService) {}
@Post()
create(@Body() createBoardDto: CreateBoardDto) {
return this.boardsService.create(createBoardDto);
}
...
}
기본 생성 코드에서 service를 정상적으로 주입받고 있습니다.
더 이상 수정할 것이 없습니다.
boards.service.ts
import { Injectable } from '@nestjs/common';
import { CreateBoardDto } from './dto/create-board.dto';
@Injectable()
export class BoardsService {
create(createBoardDto: CreateBoardDto) {
return 'This action adds a new board';
}
...
}
의존성 주입을 받고 있는 코드가 없습니다.
우리는 Repository에서 의존성 주입을 받아야 합니다.
먼저 boards.repository.ts
파일을 생성하고 boards.service.ts
파일에 아래 코드를 추가합니다.
constructor(private readonly boardsRepository: BoardsRepository) {}
import { Injectable } from '@nestjs/common';
import { CreateBoardDto } from './dto/create-board.dto';
@Injectable()
export class BoardsService {
constructor(private readonly boardsRepository: BoardsRepository) {}
create(createBoardDto: CreateBoardDto) {
return 'This action adds a new board';
}
...
}
가장 중요한 Repository입니다.
boards.repository.ts
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { BoardsEntity } from './boards.entity';
import { CreateBoardDto } from './dto/create-board.dto';
@Injectable()
export class BoardsRepository {
private boardsRepository: Repository<BoardsEntity>;
constructor(private readonly dataSource: DataSource) {
this.boardsRepository = this.dataSource.getRepository(BoardsEntity);
}
createBoard(createBoardDto: CreateBoardDto) {
...
return this.boardsRepository.save(board);
}
}
import { Module } from '@nestjs/common';
import { BoardsService } from './boards.service';
import { BoardsController } from './boards.controller';
@Module({
controllers: [BoardsController],
providers: [BoardsService],
})
export class BoardsModule {}
모듈의 providers에서 Repository를 주입받아야 합니다.
import { Module } from '@nestjs/common';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
import { BoardsRepository } from './boards.repository';
@Module({
controllers: [BoardsController],
providers: [BoardsService, BoardsRepository],
})
export class BoardsModule {}
이와 같이 Repository 패턴을 구현하면 비즈니스 로직과 DB에 접근하는 로직을 구분할 수 있어 코드의 응집성과 단일 책임 원칙을 준수하며, 유지 보수성과 테스트 용이성을 높일 수 있습니다. Bolier-Plate로 사용하며 더 좋은 구조가 있다면 개선해갈 예정입니다.
위 방법대로 구현한 예시 코드를 첨부합니다.