들어가며
안녕하세요. 셀러리 컴퍼니의 팀장 터틀입니다.
7월 6일부터 셀러리 컴퍼니의 첫 프로젝트를 시작했습니다. 본격적으로 개발을 시작하기 전에 서비스 기획, 화면 설계, 도메인 설계 등 다양한 부분에 걸쳐 회의를 진행했습니다.
합의에 도달하기까지 가장 치열했던 주제가 있었는데요, 바로 기술스택입니다. 이번 글에선 기술스택을 정하면서 어떤 부분을 논의했고 어떤 방식으로 합의했는지 다뤄보겠습니다.
기술 스택 선정 기준
먼저 저희 팀은 모두 개발자로 구성되어 있습니다. 덕분에 기획이나 화면 설계에 대해 논의를 할때도 구현을 신경쓰면서 할 수 있다는 장점이 있었습니다. 반면에 서비스가 아닌 기술에 초점이 잡히는 경향이 있었고, 기술을 적용해보고 싶은 욕심 때문에 오버 엔지니어링(over-engineering)이 되는 경우가 잦았습니다.
서비스를 개발하긴 하지만 프로젝트의 목적에 학습도 있었기 때문에 이런 부분을 마냥 배제할 순 없었습니다. 그래서 팀원들이 배우고 싶은 기술인지를 가장 먼저 생각하고, 그 다음으로 서비스에 적합한지를 고려했습니다. 하지만 배우는데 비용이 커서 개발을 진행할 수 없으면 안되기 때문에 학습 곡선 또한 고려했습니다.
위와 같은 합의를 거쳐 다음과 같은 기준이 정해졌습니다.
- 해당 기술이 많이 사용되는 기술인지
- 팀원들이 모두 배우고 싶은 기술인지
- 서비스에 적합한 기술인지
- 학습 곡선이 너무 높지 않은 기술인지
Spring Boot
팀원들은 모두 우아한 테크코스(이하 우테코)를 진행하고 있습니다. 우테코에서 Spring Boot를 학습했기 때문에 서버 환경을 Spring Boot로 구성하는 것에는 이견이 없었습니다. 사실 Spring은 엔터프라이즈 서비스에 적합하기 때문에 서비스의 규모를 생각한다면 Ruby On Rails나 Node.js를 도입하는 것이 더 적절하다고 생각합니다. 하지만 학습한 내용을 사용하자는 부분에서 합의가 이루어졌습니다.
Spring Boot를 사용하면서 Java가 아닌 Kotlin을 사용해보자는 의견도 있었습니다. 도입하자는 주장은 다음과 같습니다.
- 최근에 많은 기업에서 도입하는 추세다.
- 팀원들 모두 배워보고 싶어한다.
- 기술적으로도 다양한 장점이 있다. (링크)
하지만 다음과 같은 의견으로 무산되었습니다.
- 학습과 개발을 병행해야 하는 비용이 크다.
- 언어의 패러다임이 다르기 때문에 Kotlin을 Kotlin답게 사용하기 위한 학습 곡선이 높다.
- 잘 하는 사람이 있어야 하는데, 기술을 리딩할 사람이 없다.
기존에 정해놓은 기준은 대부분 충족했지만 학습 곡선때문에 일단락되었습니다. 무산된 이유가 학습 곡선인 만큼, 기능 구현이 마무리된 후 특정 모듈을 Kotlin으로 개발해보거나 기존의 Java 코드를 Kotlin으로 변경해보자는 방향으로 합의되었습니다.
Spring Data JDBC vs Spring Data JPA
ORM 중에선 Spring Data JDBC(이하 JDBC)와 Spring Data JPA(이하 JPA)를 사용하자는 의견이 있었습니다. 우테코에선 JDBC를 학습했지만 예상 외로 JDBC를 사용하는 방향으로 흘러가지 않았습니다.
- JPA가 많이 사용되고 있고, 앞으로 보게될 대부분의 레거시 코드 역시 JPA일 것이다.
- JPA가 제공하는 기능이 더 많다.
- JDBC를 사용하려면 DDD 설계를 따라야 하는데 그렇게 설계하고 유지하기 쉽지 않다.
하지만 JPA가 복잡하다는 이유로 Simple을 주장하며 JDBC가 나온 만큼, JPA를 사용하면서도 Aggregate간 참조 시 객체가 아닌 id로 참조하는 등 좋은 설계를 유지하도록 노력해야 할 것입니다.
학습에 대한 부분에서도 JDBC를 학습했었기 때문에 JPA는 해볼만 하다는 의견이 대부분이였습니다. 흥미와 학습 곡선의 기준을 모두 충족해 JPA를 사용하기로 합의했습니다.
웹 vs 모바일
플랫폼 중에선 웹과 모바일의 선택지가 있었습니다. 하지만 모든 팀원들은 모바일이 서비스에 더 적합하다고 생각했습니다. 팀원들 모두 중고 거래를 할 때 모바일로만 하고 웹으론 거래 하지 않기 때문입니다.
하지만 학습에 대한 부분을 고려할 때 팀원들 모두 프론트엔드 진영에서 유명한 React나 Vue.js를 배우고 싶어했습니다. 서비스를 생각한다면 모바일을, 학습을 생각한다면 웹을 선택해야 하는 상황이었습니다.
기술에 대해 찾아보던 중, React Native를 사용하면 React를 통해 모바일 플랫폼을 개발할 수 있다는 사실을 알았습니다. 학습하고 싶은 기술과 플랫폼이 맞아 떨어져서 모두 만족했습니다. 또한 React를 통해 개발하기 때문에 추후에 웹으로 확장도 가능하다는 점도 장점이었습니다.
이렇게해서 플랫폼 중에선 모바일을 선택하게 되었습니다.
React Native vs Flutter
모바일 프레임워크 중에선 React Native와 Flutter를 고민했습니다. 위에서 말한 것 처럼 학습에 대한 목적도 있어서 React Native를 선택했지만 Flutter에서 제공하는 강력한 기능을 무시할 수 없었습니다.
React를 통해 모바일 플랫폼을 개발하는 React Native는 View만 담당하는 React의 철학을 따르기 때문에 서드파티 모듈들을 매번 찾아서 직접 추가해야하는 번거로움이 존재합니다. 다양한 모듈을 찾아서 적용하는것 또한 비용이기 때문에 Flutter를 고민하게 되었습니다. Flutter에선 많은 기능과 애니메이션 등을 제공하기 때문에 다른 모듈을 찾는 비용을 최소화할 수 있습니다. Flutter는 또한 객체 지향 언어인 Dart로 개발하기 때문에 Java 개발자인 팀원들이 조금 더 쉽게 다가갈 수 있다는 점도 매력적이였습니다.
하지만 다음과 같은 이유로 React Native를 사용하기로 했습니다.
- Expo를 통해 대부분의 기능은 서드파티 모듈 없이 구현할 수 있다.
- 현재 기획한 기능은 모두 native 코드 조작이 필요없다.
- React를 학습할 수 있다.
JavaScript vs TypeScript
팀원들 중 대부분은 JavaScript(이하 JS)에 경험이 있긴 하지만 미숙했습니다. JS는 타입이 동적으로 정해지는 특성이 있어서 에러가 발생할 여지가 많았습니다. 하지만 JS를 학습해야 한다는 필요성은 모두 느꼈기 때문에 JS와 React Native로 기술스택이 정해지고 있었습니다.
그러던 중 대부분의 라이브러리가 TypeScript(이하 TS)로 변경되고 있다는 사실을 알게되었습니다. TS는 JS의 단점을 보완한 언어로, 정적으로 타입이 정해지기 때문에 컴파일 타임에 에러를 잡을 수 있고, IDE의 지원을 더 받을 수 있는 장점이 있었습니다. 이러한 장점 때문에 프론트엔드 진영에서도 대부분 TS를 사용하는 추세였습니다.
처음엔 TS와 React Native를 모두 학습하는 것이 버거울 것 같아 결정을 보류했습니다. 하지만 React Native를 사용할 때도 결국 PropType을 통해 타입 검사와 유효성 검사를 진행한다는 사실을 알았습니다. 또한 React Native를 TS로 개발할 때 사용하는 문법도 한정적이라서 금방 익숙해질 수 있다고 생각했습니다.
저희가 배운 Java 역시 정적으로 타입이 정해지는 언어이기 때문에 학습 곡선도 조금은 낮아질 것으로 예상했고, 어차피 JS를 배울거면 TS로 시작해도 괜찮다는 의견이 있어서 TS를 사용하기로 했습니다.
마치며
최종적으로 백엔드에선 Java, Spring Boot, Spring Data JPA, 그리고 프론트엔드에선 TypeScript, React Native로 기술 스택이 정해졌습니다. 이 밖에도 React Native 프레임워크인 Expo, 테스트 라이브러리인 Junit5를 사용합니다. 이 부분은 팀원 모두 당연히 써야한다고 느낀 부분이라 논의가 없어서 글에서 다루지 않았습니다.
학습에 비중을 둔 만큼 앞으로도 학습해나가며 프로젝트를 진행할 계획입니다. 많이 응원해주세요.🙂
읽어주셔서 감사합니다.