01 - 프로젝트 소개
평생 공부하는!
혼자 공부하다가 지친!
공부하는 방법 자체가 역량인!
개발자들을 위한 스터디, 모각코 등 모임을 게시하고 참여할 수 있는 커뮤니티 <모잇>
인접한 곳에서 함께 일하는 개발자들과 같이 공부하고, 작업할 수 있는 커뮤니티를 활성화하기 위해서 모잇
프로젝트를 기획했습니다 🙂
02 - 서비스 아키텍쳐



03 - 기술적 의사 결정
💻Front-End
요구사항 |
고려한 기술 |
기술 선택 이유 |
프로젝트 빌드 |
Vite |
- ES 모듈 기반의 빌드 시스템을 사용하여 브라우저가 필요로 하는 코드만 빌드하므로 번들 크기를 최소화하고 초기로딩 속도를 향상시킨다. |
- 기존 cra는 사용하지 않는 기능까지 전부 설치되기 때문에 모듈 사이즈가 크다.
- 절대경로 설정이 편리하다. (별도의 라이브러리 추가 없이, vite.config.ts, tsconfig.json에서만 변경하면 된다.) |
| 프로젝트 언어 | TypeScript | - 정적 타입의 컴파일 언어로 코드 작성 단계에서 타입 에러를 잡아낼 수 있다.
- 변수나 함수의 타입을 명시해 작성자의 의도를 명확하게 전달할 수 있다.
- 정의된 타입은 이후 자동완성을 제공해 휴먼에러를 줄이고, 생산성을 향상시킨다.
- 서버로부터 받는 response와 같이 정해지지 않은 데이터에 대한 타입을 미리 명시할 수 있다. |
| 페이지 라우팅 | React-router | - 프로젝트의 상황에 맞게 사용할 수 있는 다양한 라우터 API를 제공한다.
- 중첩라우팅을 위한 Outlet, 페이지 이동에 사용하는 Link 등의 컴포넌트를 제공한다.
- useParams, useLocation 등 경로와 관련된 다양한 훅을 제공한다.
- 다른 라우팅 라이브러리와 비교했을 때 많은 레퍼런스가 존재한다. |
| 스타일링 라이브러리 | Styled-Components | - CSS-in-JS 형식으로 css파일이 해당 컴포넌트 범위로 한정되므로 전역 스코프의 스타일 충돌을 방지할 수 있다.
- prop으로 내려받아 동적인 css 스타일링이 가능하다.
- 스타일을 모듈화하여 재사용이 용이하고, 스타일컴포넌트를 확장하거나 변형할 때도 상속을 통해 간편하게 적용할 수 있다.
- 서버 사이드 렌더링을(ssr) 지원하여 초기 로딩 성능을 향상시킬 수 있다. |
| 비동기 통신 | Axios | - 응답 데이터를 별도의 역직렬화없이 바로 사용할 수 있다.
- fetch에 비해 에러 핸들링을 간단하게 할 수 있다.
- 요청 및 응답 시 interceptor 기능을 활용할 수 있다.
- baseURL 및 디폴트 header를 설정할 수 있다. |
| 서버 상태 관리 | Tanstack/React-Query | - 서버로부터 받는 데이터의 캐싱 및 캐싱 전략으로 서버와의 통신을 최소화할 수 있다.
- 라이브러리에서 제공하는 다양한 옵션으로 api요청 및 결과와 관련된 로직들을 간단하게 처리할 수 있다.
- 프론트 상태와 서버 상태를 분리해 관리할 수 있으며, 리덕스 사용 시 비동기 작업을 위한 코드 등의 추가 작업을 크게 줄일 수 있다. |
| 실시간 채팅 기능 | Sockjs-client | - SockJS는 웹소켓을 지원하지 않는 브라우저에 대한 *대체 방법을 제공하며, 클라이언트와 서버 간 통신을 가능하게 한다.
*대체 방법 : WebSocket을 지원하지 않는 경우에는 폴백(fallback) 메커니즘을 사용하여 다양한 트랜스포트(예: HTTP long polling)를 통해 통신
- SockJS-client와 StompJS를 사용하면 서버와의 소켓 연결 상태를 쉽게 관리할 수 있어,
연결이 성공했을 때와 실패했을 때의 처리, 연결이 끊겼을 때의 자동 재연결 등을 다룰 수 있다. |
| 실시간 채팅 기능 | Stompjs | - STOMP는 단순하고 텍스트 지향적인 메시징 프로토콜로, Spring과 호환되며 구독 방식을 통해 효과적인 통신을 제공한다.
- JavaScript에서 사용할 수 있도록 지원하는 라이브러리인 StompJS 라이브러리를 사용하였다.
- 서버의 특정 주제(topic)에 구독(subscribe)하여 메시지를 수신하고 처리할 수 있다. 이를 통해 실시간 업데이트나 이벤트 기반 통신을 구현할 수 있다. |
| 지도 기능 | react-kakao-maps-sdk | - 네이버 지도 api 와 비교해 공식문서가 잘 갖춰져 있으며, 관련 레퍼런스를 많이 확보할 수 있다.
- 카카오 맵 sdk를 사용할 경우 리액트 프로젝트에서 보다 쉽게 지도 기능을 적용할 수 있으며, 제공하는 API를 활용해 원하는 기능을 빠르게 구현할 수 있다. |
💻Back-End
요구사항 |
고려한 기술 |
기술 선택 이유 |
CI/CD |
- GithubActions |
|
- Jenkins
- Docker | ✅ GithubActions
- GithubActions는 잘 만들어진 템플릿을 통해 간단하게 CI/CD 설정이 가능했으며, 무엇보다 Github와 연동되어 접근성이 좋았습니다.
❌ Jenkins
- Jenkins는 참고할 자료가 다양했지만, 알아야 할 설정들이 많았습니다.
- 플러그인 의존성이 높아, 플러그인 업데이트가 있을 경우, 개발자가 업데이트를 추적하여 유지보수해야하는 단점이 존재했습니다.
- AWS Infra구성이 변경될 경우, 이에 따른 플러그인 추가 관리가 필요한 것으로 예상이 됩니다.
————————————————————————————————————————————————————————————-
✅ Docker
- 도커는 컨테이너화된 환경을 제공했기 때문에, 개발 환경과 운영 환경의 일관성을 유지할 수 있습니다.
- 또한, 컨테이너 기반으로 가볍게 배포할 수 있었기에, 해당 기술을 선택했습니다.
- Docker Hub를 통해 CI/CD 환경을 편리하게 구축할 수 있었습니다. |
| 동적 쿼리 | - QueryDsl
- JPQL | ✅ QueryDsl
- 컴파일 시점에 타입을 체크하여 오타나 잘못된 속성을 사용하는 오류를 사전에 방지하여 안전한 쿼리 작성이 가능했습니다.
- 동적 쿼리를 쉽게 작성하고 변경할 수 있어서 유지보수가 용이하며, 코드의 가독성과 이해도를 높일 수 있었습니다.
- 복잡한 Join문과 Where 조건절을 간편하게 작성할 수 있었습니다.
✅ QueryMethod
- 간단한 쿼리는 QueryMethod를 통해 작성했습니다.
❌ JPQL
- 서비스 특성 상 특정 위치 기반 모임 조회 등 동적 쿼리를 자주 사용하는데에 반해, JPQL 은 문자열로 구성되어, 동적 쿼리를 구성하는 것이 어렵습니다.
- 가독성이 떨어져 유지 보수가 어렵습니다. |
| 로그인 | OAuth2.0 | ✅ Oauth2(소셜 로그인)
- 사용자가 가장 편안한 방법을 선택할 수 있어 사용자 경험 측면에서 이점이 있습니다.
- OAuth2 공급자(카카오, 네이버 등)가 제공하는 보안 메커니즘을 활용하여 자격 증명을 시스템에 노출하지 않고 사용자를 인증할 수 있습니다
- OAuth2는 비밀번호가 아닌 토큰을 사용하기 때문에 도용의 위험이 줄어듭니다.
❌ 일반 로그인
일반 로그인 시스템에는 일반적으로 사용자 이름/비밀번호 조합이 포함되고, 이는 비밀번호 추측, 피싱 공격, 무차별 공격과 같은 취약성에 취약할 수 있습니다. |
| 실시간 채팅 기능 구현 | - STOMP
- Long Polling | ✅ STOMP over WebSocket
- Spring 의 내장 spring-websocket 모듈 통해 쉽게 구현 가능합니다.
- 단순히 웹소켓을 사용할 때와는 다르게, STOMP에는 메시지의 형식, 유형, 내용 등을 정해져있어 별도로 개발자가 규격을 정하지 않아도 메시지를 쉽게 전달할 수 있습니다.
❌ Long Polling
- 클라이언트가 서버에 요청을 보내고 서버가 새로운 데이터가 있을 때까지 응답을 보류하는 방식입니다.
- 모임별 채팅의 양은 많을 것으로 예상되어, 서버 부하와 네트워크 오버헤드의 부담을 느낍니다. |
| 위치 기반 모임 리스트 구현 | - MySQL
- PostgreSQL | |
04 - 추후 개발 및 기술적인 도전 계획