[nest.js] Custom Repository

nest.js typeorm 0.2.x 까지는 @EntityRepository 데코레이터를 사용해서 쉽게 주입이 가능해 졌으나 0.3.x 로 올라가면서 deprecated 되었다. 아무래도 deprecated 된 건 꺼림칙하다.

custom repository를 포기하는건 거의 실무에선 불가에 가까운데 다행히도 기존처럼 사용 가능하다.

본인도 nest.js를 한지 한달도 안된 상태라 깊게는 모르므로 간략히 이해가는 선에서 정리한다.

필요한 파일과 개념

  1. decorator
    자바의 annotation. 주입에 필요한 파일이다. module 에서 동적으로 import 하기 위한 준비물
  2. module
    nest.js 에는 필수로 module 이라는 정의서가 필요하다. c++로 치자면 헤더같은 존재로 사용하는 controller와 service에서 필요한 라이브러리들을 미리 정의한 파일이다. module 을 통해 주입이 가능해 지므로 필수 지식이다.
  3. custom repository
    repository 를 상속받아 구현한 클래스. 자바의 mybatis xml 이라고 보면 된다.
    query builder를 통한 db 로직이 들어간다.

실제 소스코드 예

decorator

import { SetMetadata } from "@nestjs/common";
// import { BaseEntity } from "typeorm";

export const TYPEORM_EX_CUSTOM_REPOSITORY  = 'TYPEORM_EX_CUSTOM_REPOSITORY ';

export function CustomRepository( entity : Function ) : ClassDecorator
{
	return SetMetadata( TYPEORM_EX_CUSTOM_REPOSITORY , entity );
}

module

import { DynamicModule, Provider } from "@nestjs/common";
import { TYPEORM_EX_CUSTOM_REPOSITORY } from "./typeorm-ex.decorator";
import { getDataSourceToken } from "@nestjs/typeorm";
import { DataSource } from "typeorm";

export class TypeormExModule
{
	public static forCustomRepository<T extends new ( ...args : any[] ) => any>( repositories : T[] ) : DynamicModule
	{
		const providers : Provider[] = [];

		let entity;
		for ( const repository of repositories )
		{
			entity = Reflect.getMetadata( TYPEORM_EX_CUSTOM_REPOSITORY, repository );

			if ( !entity )
				continue;

			providers.push(
				{
					inject : [getDataSourceToken()],
					provide : repository,
					useFactory : ( dataSource : DataSource ) : typeof repository =>
					{
						const baseRepository = dataSource.getRepository<any>( entity );
						return new repository( baseRepository.target, baseRepository.manager, baseRepository.queryRunner );
					}
				}
			);
		}

		return {
			exports : providers,
			module : TypeormExModule,
			providers
		};
	}
}

custom repository

import { Repository } from "typeorm";
import { Board } from "./board.entity";
import { CustomRepository } from "./typeorm-ex.decorator";

@CustomRepository(Board)
export class BoardRepository extends Repository<Board>
{
	async findAllByAuthorID( authorid : string ) : Promise<Board[]>
	{
		return await this.createQueryBuilder( 'board' )
			.where( 'userId = :userId', { userId : authorid } )
			.getMany();
	}
}

service 에서 생성자에 custom repository 를 선언하고 사용


참조

typeorm 0.3.x @EntityRepository 돌려줘~~
typeorm 0.3.x 에서는 기존에 사용하던 @EntityRepository가 deprecated 되었다.그 말인 즉슨 커스텀 레포지토리 패턴을 사용할 수 없게되었다. 눈물이 난다.. 눈물이 나 하지만 의지의 한국인은 방법을 찾아낸다. 그 해결과정을 공유해보려고 한
nestjs/typeorm 0.3.x 적용 / Custom Repository가 안 된다고?
Sequelize가 ORM이냐 아니냐를 가지고 많은 얘기가 오간다. 설명에도 대놓고 ORM이라고 말하고 있지만, Java 에서 넘어온 개발자들에게 Sequelize는 어딘가 엉성한 친구였을 것이고, TypeScript가 나온 이상, Java..

Subscribe to X세대 신입사원

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe
774-86-01972 cinnabar.3d@gmail.com