본문 바로가기

웹/Nest

[Nest] TypeORM(v0.3) 에서 Service와 Repository를 분리하는 법

🟩 Service와 Repository를 분리하는 법

TypeORM이 0.3 버전으로 되면서 @EntityRepository가 사라졌습니다. 그러면 어떻게 Repository 파일을 만들까요??

@InjectRepository()를 사용하지 않고도 Repository를 만들 수 있습니다. DataSource라는 것을 이용하면 됩니다.

 

 

🚩 user.repository.ts

// user.repository.ts
@Injectable()
export class UsersRepository extends Repository<UsersEntity> {
  constructor(private dataSource: DataSource) {
    super(UsersEntity, dataSource.createEntityManager());
  }

  async getById(id: number) {
    return this.findOne({ where: { id } });
  }
  // ...
}

repository 파일을 만들고 Repository라는 클래스를 상속받습니다. 제네릭으로 Entity를 넣어줍니다.

@Injectable()
export class UserRepository {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}
  async getById(id: number) {
    return this.userRepository.findOneBy({ id });
    // return this.userRepository.find({ where: { id } }); << 위와 똑같은 동작을 합니다.
  }
}

@InjectRepository(Entity)를 써서 주입시키는 방법도 있습니다. 위 코드와 동일하게 동작합니다.

Repository를 만들었으니 Service에서 Repository를 사용할 수 있게됩니다. 그전에 모듈에 Repository를 추가해야합니다.

 

 

🚩user.module.ts

import { UserRepository } from './../user/repository/user.repository';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entity/user.entity';

import { UserController } from './user.controller';
import { UserService } from './user.service';

@Module({
  imports: [TypeOrmModule.forFeature([User])], //User 엔티티의 Repository 주입등록
  controllers: [UserController],
  providers: [UserService, UserRepository], //프로바이더 등록
})
export class UserModule {}

provier 형태로 Repository를 넣고있습니다. 이제 Service에서도 Repository를 주입받을 수 있게됩니다.

@Module() 데코레이터는 하나의 객체를 인자로 가지며, 객체가 가질 수 있는 프로퍼티는 아래와 같습니다.

  • providers: Nest injector에 의해 인스턴스화되고, 최소 현재 모듈에서 공유될 provider의 집합
  • controllers: 인스턴스화해야 하는, 현재 모듈에 정의된 Controller의 집합
  • imports: 현재 모듈에서 필요한 provider들을 export한 import된 모듈의 집합
  • exports: 현재 모듈에 의해 제공되며 현재 모듈을 import하는 다른 모듈에서 사용할 수 있어야 하는 provider의 하위 집합

모듈은 기본적으로 provider를 캡슐화한다. 따라서, 현재 모듈의 providers에 등록되지않았거나 import한 모듈에서 export하지 않은 provider를 inject하는 것은 불가능하다.

 

😮 provier란?

nest에서 provier란 serivces, repositories, facotries, helpers등을 만합니다. 핵심은 이게 주입이 된다는 것입니다. 주입이 되는 클래스,객체들을 provier라고 할 수 있습니다.

 

🚩user.service.ts

import { Injectable } from '@nestjs/common';
import { UserRepository } from './repository/user.repository';

@Injectable()
export class UserService {
  //service에서 생성자로 repository를 받아온다.
  constructor(private readonly userRepository: UserRepository) {}
  // 요소 1개만 가지고 오기
  findOne(id: number) {
    return this.userRepository.getById(id);
  }
}

service단에서 Repository를 가져와서 쓸 수 있습니다. 하지만 여기서 @InjectRepository(User) private userRepository: Repository<User>을 써서 바로 Repository를 주입받을 수 있습니다.

 

참고

728x90