NestJS Repository Pattern 구현하기

Hansol Jeong·2023년 6월 25일
2
post-thumbnail

NestJS에서 Repository 패턴을 구현하는 방법을 알아봅니다.

강의에 따라 학습하던 중 controller-service-repository 패턴을 구성하는데 repository 부분에서 @EntityRepository() 데코레이터를 사용했는데, deprecated 메시지가 떴습니다.

GPT가 답변해준 @InjectRepository() 데코레이터도 안먹혔습니다.

NestJS에서 기본적으로 생성해주는 CRUD App은 module-controller-service 구조입니다.

service에서 비즈니스 로직을 처리하고 DB에 접근하는 작업은 repository에서 처리하도록 Repository 패턴을 구현해봅니다.

게시판 앱을 예로 만들어보겠습니다.

nest g res 명령어로 생성한 코드를 기본으로 시작해보겠습니다.

필요한 파일

  • boards.module.ts
  • boards.controller.ts
  • boards.service.ts
  • boards.repository.ts
  • boards.entity.ts

설치가 필요한 모듈

  • typeorm

Controller

기본 생성 코드

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를 정상적으로 주입받고 있습니다.
더 이상 수정할 것이 없습니다.

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

가장 중요한 Repository입니다.

  • boardRepository 객체를 private으로 생성합니다.
  • 데이터베이스로부터 BoardsRepository 인스턴스를 생성하기 위해 DataSource를 주입받습니다.
  • 생성한 BoardsRepository를 활용하여 DB에 접근하는 메서드를 구현합니다.

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);
  }
}

Module

기본 생성 코드

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로 사용하며 더 좋은 구조가 있다면 개선해갈 예정입니다.

위 방법대로 구현한 예시 코드를 첨부합니다.

profile
기록해둡시다

0개의 댓글