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에 집중한다.