타입스크립트를 이용해 개발하는 과정에서 사용할 수 있는 대표적인 ORM은 TypeORM과 Prisma입니다. 많은 사람들이 두 ORM 중 하나를 선택하는데요. 이때 두 ORM 중 어떤 것을 채택하는 것이 더 좋을지에 대해 많이 궁금하실 것입니다. 저도 마찬가지였습니다. 저는 타입스크립트 초기부터 현재까지 TypeORM을 잘 활용해오고 있었는데요. 이번에 새롭게 시작하는 프로젝트에는 TypeORM 대신 Prisma를 도입하기로 결정했습니다. 오늘은 그 이유를 TypeORM과 Prisma를 비교하며 공유해보려 합니다.
참고자료
Prisma ORM vs TypeORM | Prisma Documentation
Learn how Prisma compares to TypeORM.
www.prisma.io
TypeORM vs Prisma
TypeORM과 Prisma를 비교한 간단한 표입니다.
TypeORM | Prisma | |
패러다임 | Code-First ORM | Schema-First ORM |
모델 정의 | TypeScript 클래스 + 데코레이터 사용 | schema.prisma 파일로 정의 (선언적 방식) |
쿼리 작성 | 엔티티 메서드 또는 Repository 사용 | Prisma Client를 통한 타입 안전한 쿼리 |
타입 안전성 | 제한적 (특히 쿼리에서) | 매우 강력 (컴파일 타임에서 오류 탐지 가능) |
마이그레이션 | 수동으로 SQL 작성 또는 TypeORM CLI 사용 | Prisma Migrate로 자동 마이그레이션 생성 및 적용 |
관계 처리 | 복잡한 관계 설정 시 코드가 난해해질 수 있음 | 관계 정의가 명확하고, 연결된 쿼리도 직관적 |
성능 및 최적화 | 중간 수준, 일부 성능 문제 보고 있음 | 최적화된 쿼리 및 요청 배치 기능 제공 |
TypeORM은 사실 JAVA Spring 진영의 JPA와 상당히 닮은 ORM입니다. OOP 스타일 패러다임을 사용해 데이터베이스 내 테이블과 1:1 매핑되는 엔티티 클래스를 만드는 방식을 사용합니다. 반면에 Prisma는 스키마 기반의 ORM으로 데이터베이스 모델을 schema.prisma 파일 하나에 모두 정의합니다. 이 파일을 활용해 타입 안정성을 제공합니다. 또한 Prisma는 마이그레이션 관리와 최적화된 쿼리를 제공합니다. 아래는 Prisma를 선택하면서 느낀 장점과 단점입니다.
Prisma 장점
1. 타입 안정성
TypeORM 쿼리에서 잘못된 속성을 사용하는 경우를 컴파일 단계에서 잡지 못합니다. 즉, 다음과 같은 예시에서 에러가 발생하지 않습니다.
const user = await userRepository.findOne({
where: { wrongField: 'test'} // 🤪 문제없는거 아닌가?
});
하지만 Prisma에서는 잘못된 속성을 사용하면 이를 컴파일 단계에서 잡아줍니다.
const user = await prisma.user.findUnique({
where: { wrongField: 'test' }, // ❗️ 타입 오류 발생
});
Prisma 단점
1. enum
데이터베이스 테이블 컬럼 중 enum 타입을 사용해야 하는 경우가 있습니다. TypeORM을 사용하던 때에는 애플리케이션 레벨에서 먼저 enum을 정의하고 이를 DB에 반영했습니다. 즉, enum이라는 코드 파일을 먼저 작성하고 @Entity 코드에서 이를 import 해 사용하게 했습니다.
하지만 prisma의 경우 prisma.schema라는 스키마 설정 파일에 모든 enum을 설정해야 합니다.(제가 알기로는 외부 enum 파일 import 불가합니다) 이때 저는 도메인 모델을 만들어 사용 중이었는데요. 이 과정에 도메인 모델에 사용할 enum 파일을 따로 만들어야 한다는 문제점이 발생했습니다. 물론 prisma.schema에 작성한 enum값은 prisma client를 생성할 때 자동으로 @prisma/client 경로에 타입으로 생성됩니다. 이를 그대로 사용하면 prisma.schema에 설정된 enum을 그대로 외부에서 사용할 수 있죠. 하지만 이 경우 도메인 모델과 prisma라는 ORM 간 높은 결합도가 생깁니다. 중간에 prisma typeORM으로 교체하게 되면 도메인 모델 부분도 수정해야 한다는 뜻이죠. 저는 이런 부분이 prisma의 단점이라고 느꼈습니다.