IT

Nest.js와 TypeORM 그리고 Prisma ORM

紫紅 2023. 1. 29. 18:41
반응형

현재 회사(2020년 시점)에서 Nest.js에 TypeORM이라는 걸 붙여 프로젝트를 시작하였고, 한 달 정도 부분적으로 참여하며 느낀 장단점, 심경을 얘기해보고자 한다.

Nest.js를 선택한 배경

기존 프로젝트는 Django와 React를 사용하였다. CTO가 떠나고 새로온 PL이 환기차원에서 이것 저것 바꾸고 있었는데, 그중 하나이다.

환기차원도 있었겠지만, 조금 더 큰 이유는 크게 두 가지로 보인다.

  1. Django 2.2.x버전에선 비동기 통신을 지원하지 않아 `channels`를 이용하여야 한다
  2. 프론트엔드를 Angular로 대체함에 따라 프론트엔드 개발자가 백엔드 코드를 볼 수 있다

그 밖의 부수적인 이유

  • 타입이 있다(유지보수, 자동완성 등에 강점, 개발자의 대체 가능성에 유연)
  • 보편적인 클린 아키택처 구조(개발자의 대체 가능성에 유연)

장점

Angular와 구조가 똑같다

Angular를 사용하는 사람이라면 아마도 당연히, 사용하지 않더라도 구조가 같음에 대해 들어봤을 것이다. 구조는 스프링과 동일하다. DatabaseProvider(Angular는 ContentProvider) -> Service -> Controller 순 혹은 역순으로 데이터가 이동하며 처리된다.

구조만 같은 게 아니라, 프로그래밍 언어, 네이밍룰 등 같은 게 많아서 한쪽에 숙련도를 쌓으면 다른 한쪽도 어느정도 커버될 수 있다.

2023년 현 시점 기준

요즘 front-end framework는 React로 단일화되고 있고, Flutter같은 신흥강자들이 즐비한 상황에서 Angular와 구조가 같은 게 장점이 될 수 있을까? 오히려 이 장점을 가져가는 것보다, React를 채택해서 채용의 이점을 가져가는 게 유리해보인다.
하지만 Angular를 여전히 쓰고 있거나, Angular가 익숙한 개발자라면 Nest.js와 동일한 구조라는 점이 충분한 장점으로 작용할 수 있을 것이다.

비동기통신을 지원한다

Node.js 위에 돌아가는 것이기 때문에 기본적으로 지원이 된다.

단점

어쩌면 Nest.js의 단점이 아니라, TypeORM의 단점일지도 모른다. 허나, Nest.js는 TypeORM을 기본 ORM으로 밀고있다는 게 함정.

(2020년 기준)아직 미숙하다(2023년 기준) 커뮤니티가 작다

개발자가 미숙한 것이 아니라, 프레임워크 자체가 아직 걸음마 단계라는 게 느껴지는 부분이 상당하다. 특히 TypeORM에서 이걸 많이 느꼈다.


Java/Spring이나 Python/Django에 비하면, 여전히 커뮤니티가 작다. 하지만 2023년 현 시점에선 2020년에 비해 꽤 성숙했다. MSA, container 운영 환경에서는 결코 부족하지 않고, 성능 측면에선 확실하게 압도한다.

2020년에 비해 개선된 부분

CLI개발 모듈

CLI 개발을 위해서는 nestjs-console라는 패키지를 이용해야 했는데, 얘 혼자만 독보적이고 자유분방한 구조를 갖고 있는 느낌이었다. 2022년 쯤 Nest-commander로 대체되었는데, Nest.js다운 모듈 구성을 갖추었다.

Message Queue Libraries

이전에 비해 다양한 라이브러리가 추가되었고, 구조 또한 Nest.js다운 형태로 바뀌었다.

orm의 각종 데코레이터가 아직 개발단계이다

TypeORM의 경우, 많은 부분 안정화되었다. 필요한 많은 기능을 훌륭하게 제공하고 있다. 최근 사용한 대부분의 기능에서 개발단계인 데코레이터라서 warnning이 뜨는 경우는 못 봤다.
그리고 꽤나 직관적인 prisma라는 대안이 나왔기에, TypeORM에 대한 단점이 크게 상쇄됐다.

개발단계라는 것은 아직 검증되지 않았다는 것이다. 언제 바뀔지 모르고, 사소한 것 이상의 큰 버그 또한 언제든 있을 수 있다는 것이다.

자동으로 생성된 swagger문서가 DTO를 제대로 반영하지 않는다

가장 큰 단점이라고 느낀 부분이다. 현재 단계에선 어떻게 써도 swagger를 위한 코드를 추가 작성해주어야하는 것이 불가피하다.TypeScript에서 타입에 ?를 붙이면 null값 허용의 의미인데, 이런 것을 전혀 인지하지 못하고 required field로 지멋대로 바꿔서 swagger문서를 만들어버린다. 잘못된 주석은 혼란만 초래할 뿐이므로, 다시 작성하는 것이 백 번 옳다.고작 API 8개에 swagger를 다는 데, 100줄이 넘는 코드가 추가되었다. Sequalize는 Nest.js와 함께 써보지 않아 모르겠지만 TypeORM보단 낫지 않을까 싶다.참고로 Django에서 drf(serializers에 정의된 내용에 따라)로 개발된 API는 swagger를 위한 별도의 코드를 작성하지 않아도 100% 일치한다.

2023년 현 시점에선 Swagger 문서도 꽤 잘 만들어준다. 여전히 보완해야할 부분(type만으로도 문서화해줘야한다고 봄)이 있어보이지만, 이전에 비하면 꽤 훌륭한 수준. 다른 프레임워크와 비교했을 때, 더 이상 단점으로 뽑을 수 없다.

이상과 현실

백엔드와 프론트엔드의 언어와 구조를 동일하게 가져가면 프론트엔드 엔지니어도 백엔드 코드를 볼 수 있을 거란 이상이 있었다. 하지만 그건 이상에 불과했으며, 현실은 "볼 놈은 python + javascript라도 보고, 안 볼 놈은 뭐가 되어도 안 본다는 것"이다.

이건 2023년 현재도, 다른 어떤 일을 해도 동일한듯. 사람의 취향과 업무 성향은 바꾸기 어렵고, R&R까지 명확하게 통제하게 되면 보고 싶어도 못 본다.

결론

현재(2023년 1월)의 결론

Nest.js는 구조를 잘 잡고 가야하는 프로젝트에서 꽤나 유용하다. 생산성도 준수한 편이고, MSA환경에서 python이나 java의 프레임워크들에 비해 탁월한 성능을 보이는 건 덤. 자유도를 조금 포기하더라도, 구조적 프로그래밍이 중요한 경우라면 항상 이 프레임워크를 선택할 것이다.
자유도가 아주 중요하고, 구조적 프로그래밍을 충분히 잘 할 수 있는 상황이라면, express를 선택할 수 있겠다. 가령 client용 SDK와 API를 한번에 만들어야하는 경우라거나...

ORM은?

TS진영에선 가장 성숙한 ORM은 TypeORM이라고 본다. Nest.js와의 궁합도 꽤 좋은 편이라, 플러그인 확장이나 모델 기반 플러그인 개발에 용이한 편. Swagger관련 에러 로그도 2020년에 비하면 상당부분 개선됐다.
하지만 여전히 TypeORM특유의 함정(처음써본다면 runtime에서나 알아채게되는 오류)이 존재하므로, 숙련되지 못한 경우, 삽질할 공산이 크다.

Sequalize의 경우, 요즘 잘 쓰지 않아서 모르겠다. 커뮤니티 크기는 TypeORM에 비해 여전히 큰 것으로 알고 있지만, TypeORM의 숙련도가 충분히 올랐고, TypeORM이 성능상 이점이 있기 때문에 개인적으론 전혀 쓰지 않는다.

Prisma ORM: TypeORM의 대안

요즘 TS진영에는 Prisma라는 신종 차세대 ORM이 활개치고 있다. 투자도 크게 받았고, 빠른 속도로 발전하고 있으며, 최근 유행하는 flutter의 언어인 dart와도 궁합이 좋아서 "충분히" 대체 가능하다. DX측면에서 낮은 러닝커브와 직관적인 인터페이스는 아주 큰 장점이다. 최근 빠른 속도로 성장한 class-validator의 대안인 Typia와도 궁합이 아주 좋다.

물론 단점도 있다. TypeScript의 typeinterface는 객체나 클래스처럼 활용할 수 없다는 점에서 발생하는 모든 문제가 단점으로 작용한다. 처음부터 class로 정의했으면, 인스턴스가 아닌 상태(클래스)로 활용 가능한데, type이나 interface는 객체를 생성한 시점부터 활용이 가능해진다. prisma-clientclass를 생성하지 않으므로, 즉시 swagger 모델로 활용할 수 없다는 단점이 존재한다.
이 외에도 앞서 말한 것처럼, class로 정의되어있지 않아서 생기는 각종 문제에 끊임없이 노출된다. prisma를 선택한 경우, 필요할 때마다 class를 추가로 만들 거나, ts 컴파일러 plugin 혹은 prisma 컴파일러 plugin을 작성하거나, 적합한 plugin을 찾아야 한다. RESTfull API만을 작성한다면, TypeORM + nestjsx/crud 가 훨씬 좋은 선택지일 것이다.

개인적으론 위의 단점은 감수할만한 수준의 단점으로 여겼고, 그렇기에 대부분의 상황에는 Prisma를 채택하고 있다.

2020년 초반의 결론

참고로 2020년 2월 26일 발행한 글이었다.

 

Nest.js는 아직 더 써봐야 알 것 같고, 지금까진 나쁘지 않았다. 하지만 TypeORM은 쓰레기의 산물이라고 확신한다. API개발이 목적이라면 django를 쓸 것이고, 성능을 고려해야한다면 micronaut등의 코틀린 기반 프레임워크를 쓸 것 같다.

굳이 Nest.js를 써야하는 상황이라면, 현재(2020년 2월) 단계에선 TypeORM대신 sequalize를 쓸 것이다(2년 정도 후의 미래엔 TypeORM이 좀 더 성숙해져있을지 모르니, 그때는 그때 가서 조사 후 결정해도 될 듯하다).

반응형