개발을 리딩해야하는 사람의 입장으로 생각해보면 최신 기술스택
과 기존의 기술스택
중에서 갈림길에 서있는 모습을 자주 보게된다.
주니어 개발자의 관점에서 기존의 기술스택은 낡았고, 최신 기술스택을 따라가야 높은 성능
과 높은 개발효율
을 가질 수 있는 것 처럼 보였다. 하지만 데이터가 많고 사용자도 많은 서비스를 안정적으로 운영해야 하면서 생각이 달라졌다.
그래서 기술스택을 도입할 때 고려해야할 체크리스트를 만들어보았다.
실제 경험한 몇가지를 예시를 들면,
앱 개발 시절에 로컬 데이터베이스로 오래된 SQLite 를 사용했고, 그 당시 떠오르던 Realm 이라는 로컬 데이터베이스를 도입한 적이 있었다.
sql select 성능이 좋고, 사용법도 최신 문법을 따르고 있고, 문서도 많고 커뮤니티도 잘 형성되어 있었다. 하지만 실제 서비스를 나가보니 데이터베이스 용량이 디바이스의 RAM 용량을 초과할 수 없는 크리티컬한 문제가 있었고, 앱을 많이 사용하는 유저에게 데이터가 쌓이면서 이슈가 발생하고 있었다.
급하게 불필요한 데이터를 지우는 로직을 추가해서 긴급배포를 진행했고, 문서를 자세히 다시 읽어보니 이와 관련된 경고를 문서에 단 한줄로 표현되어 있었다.
(현재 Realm 은 이 부분이 개선된 것으로 알고있다)
최근 대부분의 백엔드는 MSA(Micro Service Archtecture) API 로 기능별로 잘개 쪼개져있고, 한 페이지를 노출하기 위해 수십개의 API 를 호출하는 경우도 있다.
이러한 상황에서 여러 종류의 데이터를 중간서버에 GraphQL 로 요청하면, 중간서버에서는 여러개의 REST API 를 요청하고 받아 하나의 GraphQL 응답으로 받는 구조가 사용된다.
하지만 이 또한 단점이 존재하는데, GraphQL 의 여러 종류의 요청 안에서 빨리 받을 수 있는 데이터와 오래 걸리는 데이터가 있을 경우, 오래 걸리는 데이터에 맞춰서 한번에 데이터가 보내지게 된다. RESTful API 로 여러 요청하고, 받는대로 화면에 뿌려지는 것이 일부 데이터라도 빨리 볼 수 있어 사용성이 더 좋을 수 있다.
또한 GraphQL 은 중간서버를 하나 더 두는 구조기 때문에 네트워크 비용이 하나 더 추가되고, 그로 인한 서버 리소스 낭비와 응답시간에 손해를 볼 수 있는 구조다. GraphQL 이 항상 성능적인 이점이 있는 것은 아니다.
백엔드에서 많이 사용중인 Java 계열의 Spring 와 Javascript 계열의 Node.js 가 있다.
두 기술스택은 프레임워크인 Spring, 런타임 환경인 Node 를 비교한다면 정확한 비교가 불가능하다. 하지만 실제 각각 개발되는 부분을 비교하면, Spring 프레임워크는 서버를 개발하기 위한 boilerplate 코드(재사용가능한 코드)들을 많이 제공해서 코드가 어느정도 획일화가 되는 반면, Node.js 는 기본적인 기능 이외에는 아무것도 제공되지 않아 모두 직접 구현하거나, 웹 프레임워크조차도 선택해서 사용해야 한다. Node.js 의 다형성은 자유도를 주지만, 개발자간에 완전 다른 구현이 될 수도 있다는 것이다.
(Node.js 기준으로)
1. 기술스택이 적용되면 코드 품질이 좋은가? : X 개발자간에 코드를 맞추기 위해
초기설계에 시간을 더 투자해야 할 수 있다
3. 기술스택이 유지보수가 될 것인가? : △ 유지보수가 오래 가능한 라이브러리/프레임워크를 프로젝트 초기에 선정해야 한다
7. 기술스택에 맞는 개발자를 수급하기 용이한가? : O 러닝커브가 Spring 에 비해 비교적 낮다
Redux, Recoil, Mobx, React Query, ApolloClient, Redux Toolkit
프론트엔드 개발에 꽤 큰 비중을 차지하는 것이 상태관리라고 생각되는데, 위의 라이브러리들 처럼 많은 라이브러리가 새로 개발되고 있다.
일반적으로 라이브러리에 의존성을 갖지 않게 하기위해 라이브러리를 감싼(wrapping) 형태로 사용하는데, 라이브러리의 구현이 완전히 다른 경우가 많기 때문에 설계 초기에 선택한 라이브러리를 쭉 사용하는 경우가 많다.
프로젝트의 규모가 크다면 통째로 변경되어야되는 것에 서비스 안정성 측면에 리스크가 크고, 새로 개발하는 feature 부터 적용하기에는 두개의 기술스택이 공존해야하는 리스크를 가지고 있어야 한다.
내가 진행한 신규 프로젝트는 GraphQL 을 적용하기 위해 가장 스타가 많은 ApolloClient 를 도입했고 이슈없이 잘 작동하는 것처럼 보였다.
클라이언트 브라우저에서는 아무 이슈가 없었지만, SSR(Server Side Rendering) 에서 메모리 누수가 발생했었고, 성능도 생각보다 좋지 못했다. 이를 위해 라이브러리 소스코드를 하나씩 뜯어가며 점검하고 원인을 해결했다. (ReactiveVar 에 메모리 누수가 있었고, ApolloClient 에 요청을 처리할 때 정규화처리가 매우 무거웠다)
이와 같은 사례가 있었고, 지금도 새로운 기술스택을 도입할 때 위의 체크리스트를 통해 점검하고 팀원과 의논하여 신중히 도입하고 있다.