NestJs를 선택한 이유 - 버킷 프로젝트

김현욱·2022년 8월 8일
1

개발일지

목록 보기
1/3
post-thumbnail

1. 개요

'(주) 버닝서프라이즈'라는 창업 멤버로 개발 업무를 맡게 되었습니다.
서비스 내용은 로컬비즈니스 투자 플랫폼 '버킷'입니다.
Front-End 부터 Back-End, Infra 까지 혼자 도맡아서 하는 프로젝트는 처음이었고,
실제 유지/보수를 하면서 운영해야하는 어플리케이션이었기 때문에 프레임워크 선택에 조심스러웠습니다.
NestJs 를 BackEnd Framework 로 선택하기까지의 고민을 적어보려고 합니다.

2. 배경

저의 프로그램 관련 배경이나 경험은 다음과 같습니다.

  • NFT 가상 자산 거래소 FE Developer
  • 지정헌혈 매칭 플랫폼 '피플' Co-Founder 및 FE Developer(Web, Android)
  • 각종 공모전 참여를 통한 여러가지 언어, 프레임워크 경험(Android, NodeJs, Spring 등)

개발 공부를 시작하고 나서 가장 많이 다뤄봤던 언어는 Javascript, Typescript 였습니다.
그래서 Spring 보다는 Javascript(Typescript) 로 되어있는 프레임워크를 중점으로 고민했습니다.

유저 수는 시장 반응을 먼저 확인해보는 수준으로 많지 않게 잡았습니다.
회원 수는 1000명, DAU 는 30명~100명정도로 잡았습니다.

또한 개발에 주어진 시간은 8주정도였는 데 이 안에 앱(or웹앱)과 서버를 모두 만들어야 했었다는 점도 감안해주시면 감사하겠습니다.

참고로 개발을 시작한 지는 3년정도가 되었고 아직 대학교 재학생이므로 다소 부정확한 정보가 있을 수도 있습니다. 잘못된 정보가 있다면 언제든지 피드백 주시면 감사하겠습니다.

3. NestJs 를 선택했던 이유

제가 고민했던 Framework 는 Spring, NodeJs+Express, NestJS 입니다.
( python 과 golang 들은 제가 제대로 개발한 경험이 없었고 빠르게 학습할 자신이 없어서 비교대상에서 제외했습니다. )

  1. 개발 문서가 잘 정리되어 있고 커뮤니티가 크다
  2. npm 이라는 강력한 오픈 소스 생태계를 가지고 있다.
  3. 빠르게 개발이 가능하고 Performance 또한 타 Framework 들에 비해 부족하지 않다.

1) 개발 문서가 잘 정리되어 있고 커뮤니티가 크다

개발문서는 Spring이나 Express 나 NestJS 모두 잘 정리되어있다.
필요한 내용은 대부분 다 정리가 되어있다.


출처 : StackoverFlow

위 사진은 StackOverFlow 에서 조사한 가장 인기있는 언어 통계자료이다.
2021년 기준 StackOverFlow 자료에 따르면 Javascript, Typescript, NodeJs 모두 상위 10위 안에 모두 포진해있다.
물론 Javascript 가 웹 개발을 하려면 필수로 써야하는 언어이기 때문에 상위 랭크에 위치하고 있다고 생각한다. 하지만 NodeJs 도 V8 엔진을 사용하고 있기 때문에 웹 개발자가 많다하더라도 백엔드 코드와 비슷하기 때문에 참고할 수 있는 자료가 많다고 판단했다.

Java 또한 20년 넘게 사랑받는 언어이고, 특히 한국에서 가장 많이 쓰이는 언어이다.

2) 강력한 오픈 소스 생태계

NodeJs 는 NPM 이라는 커다란 오픈 소스 생태계를 갖고 있다. npm 은 단순 계산부터 AWS S3 인증까지 다양한 기능을 제공하고 있다.

물론 무분별하게 사용하기엔 안정성 문제와 보안 문제가 있긴 하지만
넷플릭스나 페이팔 같은 큰 회사들도 NodeJs 를 사용하고 있기 때문에 npm 을 Production 수준에서 사용할 수 있다고 생각한다.

package 를 선택할 때 나의 판단 기준은 크게 2가지다.

  • 다운로드 수가 충분히 많은가?
  • publish 된 지 오래되었는가? ( or publish 를 최근에 했지만 개발자가 지속적으로 관리하고 있는가?)

2가지 기준과 레퍼런스 등을 보고 안정한 version 인지 판단하고 package 에 추가한다.

3) 빠르게 개발이 가능하고 Performance 또한 타 Framework 들에 비해 부족하지 않다.

Javascript 가 Java 보다 빠르게 개발을 할 수 있는 이유는 크게 2가지였습니다.

  1. Javascript 는 prototype-based 언어이기 때문에
    class-based object 인 Java보다 코드를 빠르게 짤 수 있습니다.
  2. client-side 와 server-side 코드가 동일하기 때문에 코드 재활용성이 높습니다.
  1. Java 는 Class 없이는 프로그래밍을 할 수가 없습니다. 그렇기 때문에 Java는 클래스 설계를 굉장히 잘해야하는 언어라고 생각합니다.
    물론 클래스를 잘 설계하면 처음 개발할 때는 시간이 오래 걸리지만 이후 기능 확장이나 유지/보수 하는 데 이점이 있습니다.
    하지만 저는 Spring을 production 수준으로 다뤄본 적이 없기 때문에
    클래스 설계와 동시에 Spring을 배우면서 진행할 시간이 부족했다고 생각했습니다.
    (+ AWS, github action 등도 경험이 거의 전무했었습니다...🥲)

protype-based language 란?
자바스크립트의 모든 객체는 프로토타입을 상속받고 있습니다.
이 때문에 Javascript 는 Java 처럼 꼭 Class 를 만들지 않더라도 프로토타입으로부터 메소드와 프로퍼디 등을 사용할 수 있습니다.

예를 들면

const arr = [1,2,3]
arr.sort(); 

Array 객체를 초기화 해주지 않았는데 sort() 함수를 사용할 수 있는 것은
arr 라는 변수가 Array 의 Prototype을 상속받고 있기 때문입니다.
더 자세한 내용은 http://www.tcpschool.com/javascript/js_object_prototype 를 참고하시면 좋을 것 같습니다.

참고 : Javascript는 dynamic type 을 지원하기 때문에 static type 만 지원하는 Java 보다 빨리 짤 수 있지만 저는 Typescript 를 사용할 것이고 dynamic type 은 최대한 사용하지 않으려고 했기 때문에 선택한 이유에서 제외했습니다.

  1. NodeJs 는 프레임워크, 라이브러리 같은 것이 아닌 Javascript Runtime입니다.
    그렇기 때문에 react, vue 등에서 짰던 로직을 nestJs, express 등에 동일하게 사용할 수 있고 이는 코드 재활용성을 높입니다.
    이러한 특징이 nodejs 는 개발속도가 빠르다고 말하는 특징 중 하나인 것 같습니다.

가장 많은 고민을 했던 부분이 Performance 와 관련된 부분이었습니다.
물론 넷플릭스나 페이팔 등 큰 기업들이 사용하고 있기에 NodeJs 의 성능은 보장이 되어있다고 생각합니다.
하지만 이 대기업들은 NodeJs 를 모든 분야에서 사용하는 것이 아니라 Spring, C 등 여러가지를 섞어서 사용하는 것으로 알고 있습니다. 그렇다면 분명 NodeJS 가 안 좋은 분야가 있다고 생각했습니다.
제가 막연하게 알고 있는 지식은 'NodeJs 는 싱글쓰레드를 사용하고 이벤트 기반 아키텍처를 사용하고 있다' 정도 입니다. 또한 Spring vs NodeJs 를 찾아 보면 해커톤이나 스타트업처럼 빠르게 결과물은 내야하는 프로젝트에서는 Node 가 좋은 선택이지만 그 외에 enterprise나 security 등에서는 Spring 이 좋다고 하는 의견이 주를 이루는 거 같습니다.
그래서 제가 자료를 찾아보면서 가졌던 생각은 다음과 같습니다.

어차피 몇십만명이 동시에 쓰는 프로젝트는 아니니까 어떤 프레임워크를 선택하든 문제 없이 동작은 할거야.
하지만 각 프레임워크의 특징 정도는 알고 사용하자

NodeJs 에 대한 여러가지 정보를 찾아보면서 정리한 내용입니다.
(Medium 플랫폼을 가장 많이 참고했습니다.)
(비교대상은 Spring boot이며 Python 의 FastAPI 등은 선택후보에 없었기 때문에 비교대상에서 제외했습니다)

- Nodejs 특징

  1. NodeJs 는 속도가 무척 빠릅니다.
    nodejs 가 타 server-side 플랫폼보다 빠른 이유는 다음 2가지 때문입니다.
  • Asynchronous 기반의 Non-Blocking I/O :
    NodeJs 는 싱글쓰레드를 사용합니다. 하지만 정말로 쓰레드를 하나만 사용한다는 의미는 아닙니다. NodeJs 를 싱글쓰레드를 사용한다고 말하는 이유는 Javascript 를 실행시키는 쓰레드가 하나라는 의미입니다.
    I/O 작업들은 Worker Thread 가 아닌 다른 곳에서 수행합니다.
    이러한 이유 때문에 non-blocking 이 가능하고 멀티쓰레드를 사용하는 다른 프레임워크들보다 빠른 속도를 낼 수 있습니다.

    Non-Blocking I/O 가 빠른 이유를 잘 설명해주는 예시가 있어서 번역/요약했습니다.
    만약 산 정상에 있는 공 100개를 산 아래로 옮겨야 한다고 가정했을 때 빠르게 옮기는 방법은 무엇일까?
    첫 번째는 공 한 개를 산 아래로 굴리고 그 공이 산 아래에 도착했을 때 다음 공을 산 아래로 굴리는 방법이고,
    두 번째는 공 한 개를 산 아래로 굴리고 그 공이 산 아래에 도착하기를 기다리지 않고 다음 공을 산 아래로 굴리는 방법이다.
    당연히 두 번째 방법이 훨씬 빠르고 효율적이다. 첫 번째 방법이 멀티쓰레드 방식이고, 두 번째 방법이 싱글쓰레드 방식이다.
    출처 : https://nilebits.medium.com/why-nodejs-is-so-fast-7f158cf6d0b0

  • Event-Driven Architecture :
    NodeJs 는 Event-Driven Architecture 을 사용합니다.
    위에 내용과 이어지는 내용인데, 대부분의 Node Module 들은 EventEmitter 를 상속받고 있습니다. 그리고 'Observer' 라고 불리는 callback 함수들(or Event handler) 을 초기화 해놓습니다. EventEmitter 를 통해 Event 를 받은 callback 함수가 실행됩니다.
    이런 아키텍쳐를 통해 NodeJs 는 I/O 작업들을 수행하면서도 다른 이벤트들을 받아 들이고 수행할 수 있습니다.

EventEmitter 란?
객체들이 서로 통신할 수 있게 해주는 노드 모듈입니다.
자세한 내용은 https://www.geeksforgeeks.org/explain-event-driven-programming-in-node-js/ 를 참고하시면 될 것 같습니다.

  1. 확장성이 매우 뛰어납니다.
    AWS, GCP 등의 서비스가 많이 쓰이고 micro service architecture 가 주목받으면서 scalability 는 굉장히 중요해졌습니다.
    특히 저희 같은 스타트업들은 초기 사용자가 없는 상태에서 작은 서버를 유지하다가 이벤트를 진행할 때 잠시 서버를 늘리고 다시 줄이고 하는 과정이 매우 중요합니다.
    이러한 관점에서 봤을 때 NodeJs가 훌륭한 대안이라고 생각했습니다.
    MVP 를 만들어야하는 입장에서 NodeJs의 Scalability 가 매력적으로 다가왔습니다.

결론
사용자들에게 배당금을 포인트 형식으로 제공하는 기능을 구현해야된다는 점,
MVP 모델이면서 빠르게 개발을 진행해야한다는 점,
쇼핑몰처럼 프로모션이나 많은 계산량이 필요하지 않다는 점을 고려했을 때
Spring 보다 NodeJS 가 더 좋은 선택이다 라는 판단을 내렸습니다.

4) NestJs 를 선택했던 이유

제가 NestJs 를 선택했던 이유는 2가지였습니다.

  1. dynamic type 을 좋아하지 않는다.
  2. NodeJs(Express 등) 만 사용하기에는 자유도가 너무 높다.
  1. dynamic type 을 좋아하지 않는다
    NFT 가상자산거래소에서 일을 했을 때 해당 프론트엔드 코드가 Javascript 로 짜여있었습니다. 프로젝트가 규모가 크지 않고 혼자 개발을 진행한다면 dynamic type을 지원하는 javascript 는 괜찮은 선택지가 될 것입니다.
    하지만 프로젝트 규모가 점점 커지고 협업을 해야하는 상황이 오면 static type이 좋다는 걸 압도적으로 느꼈습니다.
    1) 어떤 Type을 넣어야 되는 지 계속 위로가서 확인해야합니다.
    2) 만약 디버깅이나 컴파일 시에 type 에러가 나면 찾기가 너무 힘듭니다.

    그래서 저는 Typesciprt 를 사용할 예정이었고 Typescirpt 를 100% 지원하거나 Typescirpt 기반의 프레임워크(or 라이브러리)를 찾고 있었습니다.

  2. NodeJs(Express 등) 만 사용하기에는 자유도가 너무 높다.
    자유도가 높다는 점은 저한테 단점이었습니다. 아직 Server-side 의 구조를 백지상태부터 잡아갈 수 있는 경험이 부족했고, 테스트 코드, 레포지토리 생성 등 적합한 라이브러리를 알아볼 시간도 부족했습니다.

위에 2가지를 모두 해결할 수 있는 방안 NestJs 였고 아주 좋은 선택이었다고 생각합니다.

참고했던 포스팅
https://nilebits.medium.com/why-nodejs-is-so-fast-7f158cf6d0b0
https://medium.com/better-programming/node-js-vs-spring-boot-which-should-you-choose-2366c2f76587
https://selleo.com/blog/10-successful-companies-using-nodejs
https://hackernoon.com/the-advantages-of-using-nodejs-caching-scalability-and-a-rich-ecosystem-q23t33c1
https://www.netguru.com/blog/node-js-scalability
https://www.quora.com/Is-Node-js-suitable-for-creating-a-FinTech-application

profile
아 왜 안돼?

0개의 댓글