타입스크립트 꽝꽝
[TypeScript] 인터페이스를 활용한 커스텀 Repository 만들기(w.typeorm)
bimppap
2022. 3. 9. 00:48
이전 게시물에서 커스텀 레포지토리를 활용한다고 했다.
typeorm에서 커스텀 레포지토리 문서를 제공하긴 하나 typeorm에 지나치게 의존하게 된다는 느낌이 들어 인터페이스를 활용해보기로 했다.
인터페이스 user.repository.ts
export interface UserRepository {
findById(id: number): Promise<User | undefined>;
}
- 인터페이스를 사용하게 된 이유?
- 확장성. typeorm 구현체를 사용하게 될 경우, 다른 orm 라이브러리로 갈아타게 될 일이 생길 때 리팩토링 비용이 많이 들 것이다. 또한 typeorm에서만 통하는 문법이 있어 다른 개발자가 봤을 때 이해하기까지 시간이 더 걸릴 수 있다. 이에 공통으로 통용되는 방식을 차용해 접근성을 높이고, 다른 라이브러리로 갈아타기 쉽도록 인터페이스를 사용하게 되었다.
구현체 typeorm-user.repository.ts
@EntityRepository(User)
export class TypeormUserRepository
extends BaseRepository<User>
implements UserRepository
{
async findById(id: number): Promise<User | undefined> {
return await this.findOne({ id: id});
}
}
- @EntityRepository(T)
- typeorm에서 제공하는 커스텀 레포지토리 데코레이터 - BaseRepository<T>
- typeorm-trasactional-cls-hooked 라이브러리를 쓸 경우 Repository<T> 대신 사용
- 레포지토리를 사용하지 않는 경우 getRepository(T)로 대체할 수 있다. - findOne()
- typeorm 레포 제공 메소드로, 조건을 만족하는 값을 하나 가져온다
- 이런... typeorm에서만 통하는 메소드명 때문에 인터페이스로 확장하게 되었다
사용 예시
서비스 UserService
@Injectable()
export class UserService {
constructor(
@InjectRepository(TypeormUserRepository)
private readonly userRepository: UserRepository,
) {}
@Transactional()
async saveUser(user: User): Promise<User> {
return this.menuRepository.save(user);
}
async findUser(id: number): Promise<User> {
return await this.userRepository.findById(id);
}
}
저기서 @InjectRepository를 빼고 모듈을 아래처럼 짜면 주입이 될 줄 알았는데...
잘 되지 않았다...
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [
UserService,
{ provide: 'UserRepository', useClass: TypeormUserRepository },
],
})
export class UserModule {}
자바 스프링처럼 하고 싶었던 꿈은 물 건너로ㅠㅠ
결과적으로 모듈은 아래처럼 쓰였다.
user.module.ts
@Module({
imports: [TypeOrmModule.forFeature([TypeormUserRepository])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
원하는 만큼 의존성을 걷어내진 못했지만 이 정도면 충분하다고 본다.
사실 타입 스크립트 클린 아키텍쳐를 참고하면 가능할 것 같긴 하지만... 프로덕션도 아닌 과제에서 이렇게까지 할 필요가 있나 싶어서ㅎ
기회가 된다면 참고해서 다시 해보는 걸로...^ㅡ^
참고자료
https://clownhacker.tistory.com/250