Search
🛠️

기술 스택 선정

Language

Typescript

정적 타입 지원으로 컴파일 단계에서 오류를 포착할 수 있다.
DTO를 명확하게 정의할 수 있다.
<br />

FrontEnd

React

모든 팀원이 사용 경험이 있으므로, 짧은 개발 기간 내 새로운 기술에 대한 학습 비용을 줄일 수 있다.
모바일 환경에서의 사용을 목표로 하기에 SPA 개발에 용이하다.
사용자 모바일 디바이스들의 성능 차가 크지 않을 것으로 예상하기에, 사용자마다 다른 브라우징 파워를 고려하지 않는다.
모든 페이지가 로그인 후 사용 가능하므로, SEO를 고려하지 않는다.

styled components

CSS 커스텀 컴포넌트를 사용함으로써 추상화에 도움이 된다.
props로 전달해 주는 값을 실제 스타일에 적용할 수 있다.
팀 내 styled components 사용 경험이 Emotion에 비해 높기에, 짧은 개발 기간 내 새로운 기술에 대한 학습 비용을 줄일 수 있다.
또한 Emotion과 styled components의 유의미한 차이를 느끼지 못했다.

Zusthand

굉장히 쉬운 Zusthand는 상태 관리 라이브러리 사용 경험이 없는 팀에게 큰 도움이 된다.
번들 사이즈가 다른 상태 관리 라이브러리에 비해 작다.

React Query

클라이언트 데이터와 서버 데이터를 분리할 수 있다.
동일한 데이터를 여러번 요청해도 한번의 요청 이후 캐싱이 된다.
커스텀 Hook으로 분리함으로써 비동기 과정을 선언적으로 관리할 수 있다.
React Suspense와 함께 사용할 수 있어, 좀 더 편리한 로딩 화면 렌더링이 가능하다.

Storybook

컴포넌트 단위 개발을 수행할 때, 시각적인 테스팅에 용이하다.
컴포넌트 동작 예시를 문서화함으로써 협업에 큰 도움이 된다.
단, 페이지 단위 개발시 코드 작성 비용을 줄이기 위해 활용하지 않는다.

PWA

네이티브 애플리케이션을 사용하는 것과 유사한 경험을 사용자에게 제공할 수 있다.
홈 화면의 아이콘을 탭하여 쉽게 접근할 수 있도록 한다.
<br />

BackEnd

NestJS

사람마다 짜는 아키텍처가 다르면 이를 이해하기 위한 비용 또는 개발 전에 아키텍처를 선정하는 커뮤니케이션 비용이 증가할 수 있다.
NestJS는 아키텍처에 대한 정의를 제공하기 때문에 동일한 아키텍처에서 다른 개발자가 작성한 코드를 쉽게 이해할 수 있으므로 이러한 비용을 줄일 수 있다.
또한 테스트, 미들웨어 등 많은 기능을 프레임워크 자체에 포함하고 있기 때문에 라이브러리를 찾아서 검토하는 비용도 줄일 수 있어 선택했다.

RDB vs NoSQL

우리 서비스에서는 예를 들어, 채팅같은 빠른 WRITE가 필요한 기능이 없다.
약 6만개의 랭킹 데이터를 받아온다거나, 달력으로 모든 운동 기록을 조회하는 등 READ의 비중이 높다.
또한 유저, 운동 기록, 알림 등 관계를 맺고 있는 데이터가 자주 변경될 수 있기 때문에 NoSQL을 사용할 경우 데이터가 여러 컬렉션에 중복되며, 수정 시 관련된 모든 컬렉션에서 수정을 해야하는 문제가 있었다.
하여 운동, 루틴, 팔로우 등 테이블 간의 명확한 스키마 구조를 고집하고자 최종적으로 RDB를 선택했다.

MySQL

Oracle, PostgresQL 과 같은 RDB도 고려 대상이었지만, 모두가 익숙하고 무료로 사용 가능하며 만들고자 하는 서비스의 복잡도가 그리 크지 않기 때문에 MySQL을 선택했다.

ORM

ORM은 순수 쿼리보다 느리지만, 객체 형식으로 사용하여 생산성을 높여주는 장점이 있다.
또한 Nest.js를 사용하기로 한 만큼 Entity 모델을 통해 재사용성을 높일 수 있어서 선택했다.

TypeORM

TypeORM과 Prisma를 조사하는 과정에서 둘의 큰 유의미한 차이가 느껴지지 않았다.
Nest.js의 공식 문서에서 TypeORM을 바탕으로 설명하고 있었기 때문에 학습 비용이 상대적으로 적게 들 것이라 판단하여 선택했다.

swagger

프론트엔드, 백엔드 둘 다 API 연동 작업이 필요하여 하나의 API 명세서는 반드시 필요했다.
또한 Postman이라는 API 테스팅 도구도 필요했다.
하여 Nest.js와 연동하여 문서화와 테스팅 둘 다 가능한 swagger를 선택했다.
<br />

DevOps

Nginx

여러 사용자가 접속할 수 있는 서비스이기에 동시접속 처리를 위해 Nginx를 채택했다.
Apache보다 동작이 단순하여 적은 비용으로 설정할 수 있고, 전달자 역할만 하기에 동시접속 처리에 특화되어 있다.
서비스 배포를 염두해두고 있기 때문에 HTTPS가 필수적이라고 결정했고, Nginx를 통해 이를 쉽고 간편하게 설정할 수 있다.
또한 Nginx를 통해 HTTP로 들어오는 요청을 모두 HTTPS로 간편하게 리다이렉트할 수 있다.
리버스 프록시를 통해 클라이언트의 요청을 서버에 배분하여 효율적으로 처리할 수 있다.

Naver Clound

부스트캠프에서 지급해주는 20만원 가량이 크래딧이 있기 때문에 금전적 비용을 줄일 수 있어서 채택했다.

PM2

제한된 시간내에 빠르게 무중단 배포를 하기 위해 PM2를 채택했다.
PM2의 cluster mode를 통해 싱글 스레드인 Node.js를 멀티 스레드로 구동 시켜줌으로서 성능을 끌어낼 수 있다.

Let's Encrypt

https 설정을 위한 무료 인증서 발급을 위해 채택했다.
인증 절차가 단순화되었을 뿐만 아니라 발급 대기 시간이 없어 빠르게 인증서를 적용할 수 있다.
TLS 인증서 발급이 가능하며 와일드 카드 인증서를 지원한다.
발급을 위한 정보는 발급자 이메일만 요구된다.
만료된 인증서 갱신을 자동화할 수 있다.
<br />

Test

Jest

쉬운 설치 및 사용이 가능하다.
팀원 모두가 사용해 본 경험(단 한번)이 있다.
단, 테스트 비용을 줄이기 위해 유틸성 로직을 위주로 작성한다.

Cypress

BackEnd를 mocking하여 FrontEnd 통합 테스트를 할 수 있다.
브라우저의 모든 기능을 사용할 수 있다.
console.log()에 의지하는 것보다 훨씬 더 인터렉티브한 환경에서 디버깅을 할 수 있다.
단, 테스트 비용을 줄이기 위해 '실제로 사용자에게 제공하는 기능'을 기준으로 네트워크 요청과 상태 관리에 대한 mocking에 집중한다.