[Nest.JS] Repository Pattern

장현수·2023년 7월 15일
0

Nest.JS

목록 보기
4/9

Repository

Repository 종류

1. Entity

  • 말 그대로 엔티티의 테이블 행을 말한다.

2. Generic Repository

  • DB 테이블 전체를 관리하는 클래스
  • 테이블의 CRUD 작업을 한다: TypeORM 사용

3. Specific Repository Class

  • 특정 기능을 요하는 custom class

Controller

@Controller('/events')
export class EventsController {
  constructor(
    @InjectRepository(Event)
    private readonly repository: Repository<Event>,
  ) {}
  
  ...
  • 컨트롤러 작성 시 @Controller 데코레이터를 입력한다.
  • constructor 생성자 안에 @InjectRepository() 데코레이터를 입력하여 생성한 레포지토리 클래스를 의존성 주입받는다.
  • 데코레이터 안에 엔티티를 파라미터로 입력한다.
  • private 접근 제한자로 repository에 Entity 타입의 Repository 객체를 타입으로 준다.

컨트롤러 내부에 메소드를 작성한다.

READ: GET

리팩토링 전

  @Get()
  findAll() {
    return this.events;
  }

리팩토링 후

  @Get()
  async findAll() {
    return await this.repository.find();
  }
  • 메소드 데코레이터를 입력한다.
  • 메소드 앞에 async, return값에 await을 선언해준다.
  • 앞서 컨트롤러 생성 시 repository를 프로퍼티로 줬기 때문에 this.repository로 가져와 쓸 수 있다.

GET: 파라미터값을 받을 때

리팩토링 전

  @Get(':id')
  findOne(@Param('id') id) {
    const event = this.events.find((event) => event.id === parseInt(id));

    return event;
  }

리팩토링 후

 @Get(':id')
  async findOne(@Param('id') id) {
    return await this.repository.findOne(id);
  }

CREATE

리팩토링 전

  @Post()
  create(@Body() input: CreateEventDto) {
    const event = {
      ...input,
      when: new Date(input.when),
      id: this.events.length + 1,
    };
    this.events.push(event);
    return event;
  }

리팩토링 후

  @Post()
  async create(@Body() input: CreateEventDto) {
    return await this.repository.save({
      ...input,
      when: new Date(input.when),
    });
  }
  • save() 메소드를 사용한다.
  • save() 메소드는 새로운 테이블 레코드를 생성한다.
  • 이미 있는 엔티티인 경우 update한다.

Update

리팩토링 전

  @Patch(':id')
  update(@Param('id') id, @Body() input: UpdateEventDto) {
    const index = this.events.findIndex((event) => event.id === parseInt(id));

    this.events[index] = {
      ...this.events[index],
      ...input,
      when: input.when ? new Date(input.when) : this.events[index].when,
    };

    return this.events[index];
  }

리팩토링 후

  @Patch(':id')
  async update(@Param('id') id, @Body() input: UpdateEventDto) {
    // 1. 저장된 entity를 불러와야 한다.
    const event = await this.repository.findOne(id);
    // 2. entity를 수정한 후 return한다.
    return await this.repository.save({
      ...event,
      ...input,
      when: input.when ? new Date(input.when) : event.when,
    });
  }
  • 먼저, 저장되어있는 entity를 불러오기 위해 findOne 메소드를 사용한다.
  • entity를 수정하여 return한다.

Delete

리팩토링 전

  @Delete(':id')
  @HttpCode(204)
  remove(@Param('id') id) {
    this.events = this.events.filter((event) => event.id !== parseInt(id));
  }

리팩토링 후

  @Delete(':id')
  @HttpCode(204)
  async remove(@Param('id') id) {
    const event = await this.repository.findOne(id);
    await this.repository.remove(event);
  }
  • entity를 찾는다.
  • remove메소드로 entity를 삭제한다.

Module

repository를 주입하기 위해 모듈에도 임포트 해줘야 한다.

@Module({
  imports: [
    TypeOrmModule.forRoot(ormConfig),
    TypeOrmModule.forFeature([Event]),
  ],
  controllers: [AppController, EventsController],
  providers: [AppService],
})
export class AppModule {}

TypeOrmModule.forFeature([엔티티])를 추가해준다.

profile
개같이 발전하자 개발

0개의 댓글