서비스에 적합한 기술 고르기

Patrick(우종선)
ATEAM Ventures 기술 블로그
11 min readFeb 7, 2020

안녕하세요 에이팀 벤처스 기술 블로그의 첫 글을 작성하게 된 패트릭(우종선)입니다.

개발자들은 흔히 어떤 기술을 사용해서 제품을 만들지 고민하게 됩니다.

에이팀 벤처스 개발팀에서는 Typescript 를 사용해서 제조 플랫폼 크리에이터블과 고객의 주문을 관리하는 BO 크리에이터블을 개발하고 있습니다. 에이팀에서는 지금의 크리에이터블을 개발하면서 레거시인 C# .net core 를 버리고 타입스크립트 & Express를 선택했습니다.

저는 이번에 개인적으로 프레임워크를 비교하고 살펴보는 계기를 가졌습니다. 이번 글에서는 제가 프레임워크를 비교하며 살펴본 경험을 공유합니다. 이 글이 프레임워크를 고민하시는 분들에게 도움이 되었으면 좋겠습니다.

C# .net core, Java Spring, Django, Typescript 를 살펴본 이야기를 해보겠습니다.

먼저 C# .net core를 살펴보겠습니다.

C# .Net core

C#은 훌륭한 언어입니다. 언어 자체로는 그렇습니다. 처음부터 C# 은 java를 겨냥하고 나온 언어였습니다. javascript처럼 람다식도 사용 할 수 있고 C++처럼 포인터도 사용 할 수 있습니다. var 타입도 지원합니다. 기능은 정말 많습니다.

알려진 C#을 사용하는 회사는 PUBG가 있습니다.

C#을 사용했을때 단점은 이렇습니다. Node.js나 python 처럼 라이브러리가 풍부하지는 않습니다. Node.js 의 npm 에는 35만개 이상의 패키지가 등록되어 있습니다. 절대적인 라이브러리의 개수로 본다면 C# 도 적진 않습니다.

제가 문제라고 생각한 부분은 오픈소스 문화가 잘 보이지 않는다는 것이었습니다. 예를 들어서 nuget 패키지의 경우 첫 페이지를 보면 회사에서 만든 패키지를 쉽게 찾을 수 있습니다.

npm 의 경우 개인이 만든 라이브러리가 많습니다.

개인이 만들고 여러사람이 프로젝트에 기여합니다. 이렇게 되면 굉장히 다양한 라이브러리가 만들어질 수 있습니다. 그리고 많은 사람들이 함께 버그를 찾아내고 문제를 해결하게 됩니다.

이 중에서 한 패키지의 github 페이지만 들어가봐도 nuget 은 소수의 사람들이 커밋한 기록이 많습니다. npm 은 여러사람이 PR을 보내고 커밋한 기록이 많습니다.

npm 패키지에 여러사람이 커밋한 기록

깃허브 링크도 없는 nuget 패키지도 있습니다.

이런 상황은 C#에서 문제 해결에 적합한 라이브러리가 없는 경우 직접 개발해서 해결해야 한다는 것을 의미하게 됩니다. npm의 경우에는 패키지를 올리는 진입 장벽이 더 낮기 때문에 C# 보다 쉽게 문제를 해결해주는 패키지를 발견하게 됩니다.

npm 패키지 개수
nuget 패키지 개수

사용 경험에 있어서 .net Core 프레임워크의 사용경험은 Spring 과 유사합니다. 객체지향 설계를 사용하고 Controller, Model, Repository 를 정의하고 개발합니다. Nodejs 나 Python 보다는 상대적으로 작성해야 하는 코드는 많습니다. 정적언어로써 언어 자체의 성능은 좋은 편입니다.

javascript처럼 언어 차원에서 JSON 데이터를 다루는 것은 안됩니다. Auto mapper 같은 라이브러리를 사용해야 합니다.

Java + Spring boot

다음은 국내에서 가장 많이 쓰이고 있는 Java & Spring 입니다. Java 를 쓰는 회사를 대충 나열하면 이렇습니다.

네이버, 카카오, 우아한형제들, 비바리퍼블리카, 하이퍼커넥트, 쿠팡… 등 많은 회사들이 Java를 사용합니다.

프레임워크를 놓고 봤을 때 Spring 프레임워크는 거대합니다. 그리고 정말 많은 기능을 제공해줍니다. Spring Security 를 통해서 많은 인증처리를 개발할 수도 있습니다. Spring cloud를 사용하면 서킷 브레이커 패턴의 구현체를 사용 할 수도 있습니다.

서킷 브레이커 패턴은 MSA(Micro Service Architecture) 에서 장애 전파를 막기위한 아키텍처 패턴입니다. Java & Spring은 제공해주는 것도 많고 쓰는 회사도 정말 많습니다.

단점은 같은 동작을 하는 코드도 Java를 사용하면 굉장히 길어집니다. 작성해야 하는 코드도 많고 Spring 의 여러 기능들은 많은 설정을 필요로합니다.

한가지 예로 oauth인증을 구현할때 Node.js에서는 passport.js 를 사용하면 됩니다. 스프링은 Spring Security 를 사용해서 많은 부분을 구현해야 합니다.

링크를 따라가시면 Passport.js 문서가 나옵니다. 아래 코드는 문서의 일부입니다. 아래와 같은 코드를 입력하면 oauth2 인증 처리가 구현됩니다.

링크를 따라가시면 Spring Security oauth 2를 구현하는 방법이 있습니다.

Spring 에서 Spring boot가 나온 것은 좋은 발전이었지만 Spring boot 도 여전히 다른 프레임워크에 비해서 설정해야 할 것들이 많다고 느꼈습니다.

설계적인 측면에서는 C# 처럼 객체지향 설계를 사용합니다. 완전한 객체지향 설계는 Nodejs처럼 함수, 기능 단위로 설계할 때보다 오래 걸립니다.

Python + Django

다음은 Python입니다. Python 은 간결합니다. Python이 간결하다는 것은 그들의 홍보 문구에서도 드러납니다.

“life is short you need python”

Django를 사용했을때 생산성이 좋다는 이야기는 이미 널리 알려진 이야기입니다.

첫번째 단점으로 느낀 것은 Azure 클라우드를 사용하기는 어렵습니다. AKS, App service, Function, API Management 등의 많은 Azure 서비스에서 Python 은 Preview 로써 지원되거나 지원되지 않습니다. Azure 에서는 Python에 대한 지원이 굉장히 부족합니다. Javascript 같은 경우에는 어느 클라우드에서나 잘 됩니다.

알려진 Python의 다른 단점은 언어의 성능이 상대적으로 좋지 않다는 것입니다.아래 Javascript + Expressjs 에서 첨부한 벤치마크를 보시면 Django는 대체로 항상 낮은 순위에 있습니다.

Javascript + Expressjs

이번엔 Nodejs입니다. Nodejs의 프레임워크는 Expressjs 말고도 여러가지가 있습니다. 그 중에서 가장 많이 쓰이고 있는 Expressjs를 선택해서 비교했습니다.

javascript를 사용하면 몇가지 편리한 점이 있습니다.

  • javascript를 사용하면 json 데이터를 편리하게 다룰 수 있습니다. javascript는 언어 차원에서 json 데이터를 다루는 것을 지원합니다.
  • 언어차원에서 이벤트 드리븐 Nonblocking IO를 할 수 있습니다. 스프링의 경우엔 Webflux 를 써야하고 코딩 방식이 조금 달라집니다.
  • Nodejs로 만들어진 서버는 성능이 꽤 좋습니다.
출처 : http://www.techempower.com/benchmarks/#section=data-r8&hw=ph&test=query

Django 는 그림에서 가장 아래 쪽에 있습니다.

  • Nodejs는 Non Blocking I/O 가 기본적으로 지원됩니다.

최근 Java를 사용하는 네트워크 애플리케이션 framework 인 Netty 를 쓰는 사람들이 늘고 있습니다. Netty 를 쓰는 큰 이유 중의 하나는 Non Blocking I/O가 지원되기 때문입니다.

Nodejs 는 그런 별도의 Framework를 쓰지 않아도 기본적으로 Non blocking I/O로 처리됩니다. 하나의 스레드로 여러 클라이언트에 대응 할 수 있게 됩니다.

하지만 javascript를 사용하는 것은 장점만 가득하진 않습니다. Java 같은 정적언어 보다 안정성이 떨어집니다. 타입이 없기 때문에 코드를 작성할때 실수 하지 않도록 주의해야 합니다. 타입이 있으면 함께 일하기에 더 좋습니다. 타입스크립트도 살펴봤습니다.

Typescript + Nestjs

타입스크립트는 Javascript의 superset입니다. 프레임워크로는 Expressjs, nestjs 같은 것들이 있습니다. Nestjs 는 Angular.js의 개발자들이 만들었습니다. Nestjs 는 편리한 점이 많았습니다. 조금만 소개해드리면 이렇습니다.

Swagger 문서화가 굉장히 쉽습니다. swagger 문서를 만들고 싶다면 아래 코드 정도만 작성하면 됩니다.

Class-validator 를 사용한 validation도 굉장히 편리합니다.

class-validator 모듈의 애너테이션을 붙여주고 bootstrap() 함수에 ValidationPipe()를 한 줄만 추가해주면 됩니다. 다른 많은 것들이 이렇게 편리합니다.

Nestjs에서는 CLI도 제공하기 때문에 장고처럼 커맨드라인으로 프로젝트를 만들 수도 있습니다. NestJS는 프로젝트를 만들면 틀이 다 짜여진채로 만들어집니다. 이건 틀이 없는 Expressjs 가 단점이라고 생각한다면 큰 장점으로 볼 만 했습니다. 틀이 다 짜여진채로 개발을 한다면 같이 개발할 때 비슷한 결과를 낼 수 있습니다. 이렇게 되면 유지보수가 편리해집니다.

하지만 한 가지 이상했던 점이 있었습니다. Nest js에서는 class를 타입으로 사용합니다. 이렇게 되면 프론트엔드 웹에 Typescript 를 적용했을때 공통 모듈에 타입을 정의하고 쓸 수 없게 됩니다. React 와 같은 프론트엔드 웹에서는 interface를 타입으로 쓰기 때문입니다. 타입 스크립트 공식 문서에서도 타입을 interface로 쓰고 있습니다.

개발하는 제품의 클라이언트 앱이 Angular 로 만든 웹이라면 NestJs는 좋은 선택지가 되었을 것 같습니다. 아니면 안드로이드/IOS 앱이어도 서버와 같은 타입 모듈을 사용할 수 없으니 NestJS가 좋은 선택이 되었을 것 같습니다.

NestJS 는 사용 경험이 Spring 과 정말 비슷합니다. 설치하는 모듈도 굉장히 많습니다. @ 애너테이션도 많이 씁니다. Model도 만들고 객체지향적으로 개발을 합니다.

이건 Express & Nodejs 를 사용했을 때만큼 가벼운 마이크로서비스를 만들지는 못한다는 단점이 있습니다. Nodejs는 Java가 아닌데 Java 의 객체지향 철학을 어디까지 수용하는게 합리적일지 판단하는 것도 문제였습니다.

Nodejs는 Java처럼 실제 세계를 복제하는 객체지향 설계를 지향하지 않습니다. 이건 이런 페이지Nodejs 디자인 패턴 이라는 책에서도 이야기 하고 있습니다. Nodejs는 복잡하지 않고 실용적인 접근을 선호합니다. Nestjs를 하게되면 javascript 로 하는 Spring 을 하는 느낌이었습니다. Express 를 쓰는게 더 Nodejs 의 철학과 부합한다는 생각이 들었습니다. 이 부분은 사람에 따라 의견이 많이 갈릴 것 같았습니다.

Typescript + Express

타입스크립트와 Express입니다. Express는 가장 많이 쓰이는 javascript web framework 입니다. Express 를 사용하면 NestJS처럼 정해진 틀이 없습니다.편한대로 구조를 만들어 나갑니다. 필요한 것들만 추가하면서 최소한의 크기로 마이크로 서비스를 만들어나갈 수 있습니다. 구조를 직접 만들어가야 한다는 것에는 사실 저는 조금 거부감이 있었습니다. 누가 만들어도 똑같은 구조로 만들도록 틀이 잡혀있는 것이 협업하기엔 더 좋아보였습니다. 이 부분은 Bolilerplate를 합의하고 그로부터 개발한다면 해결 할 수 있을 것입니다.

Typescript 는 당연히 입출력으로는 Nodejs의 Non-Blocking I/O를 사용합니다. 비동기 처리를 짧은 코드로 작성할 수 있습니다. javascript 와 비슷한 코드 길이를 가집니다. 타입은 Typescript 문서에서 권장하는 interface를 사용합니다.

다만 Spring에서 제공하는 Hystrix같은 건 사용 할 수 없습니다. MSA를 모니터링 하고 싶다면 Istio 같은 솔루션을 사용해야 합니다.

--

--