프로젝트 개요 - 3분 이내
1. 인사 및 팀 소개
안녕하세요 2조 카북 팀의 발표를 시작하겠습니다.
저희 프로젝트의 프론트엔드는 김은아, 정동환 님이, 백엔드는 임수민, 이재훈, 최주형 님이 담당했습니다.
2. 프로젝트 소개
- 개발 동기
- 저희는 피그잼을 통해 브레인스토밍을 진행했고, 여러 가지 주제 중 프로젝트 기간과 구현 사항, 도전 가능한 목표들, 팀워크를 위한 역할 분배를 고려해 최종적으로 차량 공유 SNS 주제를 선택하게 되었습니다.
- 프로젝트 간단 소개
- 서비스 이름은 “카북”으로, 차를 사랑하는 사람들이 친구들과 자신의 멋진 차량 사진을 공유할 수 있는 SNS 입니다.
- 사용자는 차 모델과 종류를 입력하고 자신이 원하는 해시태그를 차량 사진과 함께 게시물을 올릴 수 있으며, 다른 사용자는 자신이 원하는 해시태그를 검색하여 필터링 되어진 차 사진을 볼 수 있습니다.
- 시스템 구성도
- 기술 스택
- FE : Ts(언어), vite(번들러), sass(BEM), axios, eslint, prettier(코드 포맷터)
- BE: Spring, MySQL(DB), jdbctemplate(DB 매핑 기술)
- ci/cd: AWS (EC2, S3), Github Actions 자동화 (쉘)
- 시스템 아키텍처
- 배포 아키텍처
문제 해결 - 7분 이내
3. 기능 구현 - 2분 이내
저희 팀은 기능을 구현하기 전 팀 컨벤션을 정하여 브랜치 네이밍, 이슈 및 pr 머지 방식, 코드 리뷰 등에 대해 협의 하였습니다.
또한 백엔드와 프론트엔드 개발 간의 원활한 커뮤니케이션을 위해 포스트맨을 사용하여 api 요청 및 응답에 대한 명세서를 함께 작성하였습니다.
1) 프론트엔드
프론트엔드는 타입스크립트을 활용하여 타입스크립트의 장점을 최대한 활용하기 위해 OOP 방식으로 기능을 개발하였습니다. 또한 컴포넌트 구조를 기반으로 프로젝트를 설계하여 코드의 재사용성과 응집도를 높였습니다.
부모 클래스인 컴포넌트는 state를 가지며 state가 변경시 해당 컴포넌트가 렌더링 되도록 설계하였고 모든 요소들은 해당 클래스를 상속받아 같은 구조를 가지게 되어 코드의 일관성을 유지하였습니다.
2) 백엔드
백엔드는 API 명세서를 바탕으로 서비스에 사용되는 API를 구현하였습니다. - API 리스트를 보여주며
저희는 각 기능의 테스트 코드 작성에 많은 노력을 했습니다. 컨트롤러, 서비스, 리포지토리 단 각각의 테스트 코드를 mock 라이브러리를 사용해 작성하였고, 특히 리포지토리단 테스트는 실제 mysql db를 사용하지 않고 테스트용 인메모리 DB를 통해 빠르게 테스트하고 있습니다.
추가 - 테스트 커버리지 내용 추가
4. 도전적인 내용 - 5분 이내
BE
- AWS S3를 사용하여 이미지 저장
- 게시글의 이미지를 s3 저장소에 저장하였습니다. 프론트에서 넘겨주는 이미지 파일을 백엔드에서 s3와의 연동을 통해 업로드하였습니다. 또한 프론트에서 s3 이미지를 백엔드를 거치지 않고 이용하는 경우를 위해 s3의 cors 설정을 해주었습니다.
- 무한 스크롤
- 저희 팀은 메인 페이지를 보여줄 때 글 목록을 무한 스크롤을 사용하여 게시글을 보여주고 있습니다. 프론트엔드에서 URL의 쿼리 파라미터로 인덱스를 넘기면 백엔드에서는 offset을 사용한 페이지네이션을 통해 프론트엔드로 데이터를 넘겨주고, 프론트엔드에서는 전체 데이터가 아닌 부분적으로 데이터를 불러오면서 렌더링을 보다 최적화 하였습니다.
- 하지만 이 방식은, 추가로 글이 생성되면 글이 중복되어 보일 수 있고, 글이 삭제되었을 때는 사용자가 보지 못하는 글들이 생길 수 있습니다. offset을 사용하면 백엔드에서는 현재 사용자가 어떤 게시글까지 봤는지 알 수 있는 방법이 없기 때문입니다.
- 이러한 문제점을 개선하기 위해, 벡엔드가 응답을 보낼 때 가장 마지막으로 조회한 게시글 id를 넘겨주고, 프론트에서 다음으로 요청을 보낼 때 응답 받은 게시글 id를 보내어, 글이 중복되거나 사용자가 보지 못하는 페이지가 없도록 수정 중입니다.
- 좋아요 성능개선 - ERD
- sns의 핵심 기능인 좋아요를 구현할 때 성능적 이슈가 발생하였습니다. 기존의 방식에서는 좋아요 테이블을 만든 뒤, 매 게시물마다 좋아요 테이블에서의 count를 통해 좋아요 수를 도출하였습니다. 그러나 sns의 특성 상 유저가 많아질수록 게시물 또한 많아지며, 이러한 방식은 성능적 저하를 발생할 수 있다고 느꼈습니다.
- 이에 따라 반정규화를 통해 좋아요 수를 게시글 테이블에 추가하기로 결정하였습니다. 이 경우 좋아요 Table을 거칠 필요 없이 게시글 table만으로 좋아요 수를 알 수 있기에 성능 개선이 가능합니다.
- 그러나 반정규화를 한다면 동기화 문제가 발생됩니다. 다중 유저가 동시에 좋아요를 누를 때, 데이터 정합성에서 문제가 발생가능하기 때문입니다. 이에 대한 해결책으로 조회에 lock을 건다던가, select와 update를 분리하지 않고 한번에 하는 방식이 있지만, 성능적으로 좋지 않습니다. 따라서 평소에는 데이터 정합성을 맞추지 않고, 주기적으로 정합성이 맞도록 update하는 스케쥴러 방식을 선택하였습니다.
FE
- redux 로직 구현
- 저희 프론트 팀은 redux라이브러리를 이용하지 않고 직접 구현하여 전역적으로 관리되어야 하는 데이터의 변경에 따른 렌더링을 최적화했습니다.
- 이벤트 중복문제
- 컴포넌트 방식은 렌더링할때마다 setEvent함수가 호출돼어 이벤트가 중복으로 등록되는 문제가 있었습니다.
- 페이지 이동시에는 기존 돔을 비우고 새로 돔을 생성하는 로직을 추가하여 페이지 이동시 이벤트가 쌓이는 문제를 해결했습니다.
- 그리고 페이지가 처음 setup 됐을때만 이벤트가 등록되도록 구현했습니다.
5. 팀 활동 - 팀워크로 어려운 점 극복 - 5분
시나리오를 어떻게 정할 것인가
백엔드 개발이 초보임을 강조하고 도전했다는 모습을 어필
백엔드 팀 도전 사례 - 배포, Repository 테스트 인메모리 db 사용
혼자 도전해서 어떻게 해결했는지 보다 어떻게 협업해서 해결했는지
동작 데모 - 5분 이내
- 메인페이지(비로그인)
- 태그 검색 (카테고리 선택하는거 보여주세요)
- 맑 > 맑음
- 무한 스크롤 되는 부분을 보여줌
- 태그를 추가만 하고 필터링이 된다. 하지만 태그를 없애지마
- 다른곳 로그인 해야 들어갈 수 있음
- 회원가입 - 할 수있다. 굳이 하지 말자
- 로그인 (새로고침 한번 하고) - 테스트 계정으로 로그인
- 메인페이지(로그인)
- 내가 팔로잉한 사람들의 게시물을 볼 수 있는 부분
- 프로필페이지
- 내 게시물 목록
- 팔로워 페이지로 이동
- 팔로잉 누르고 돌아오기
- 팔로워 목록
- 팔로워 삭제 되는데 숫자 안바뀜
- 팔로잉 목록
- 되는데 숫자 안바뀜
- 회원정보 변경 (닉네임 변경 보여주기)
- 로그아웃이 된다 하지만 로그아웃을 하지 않는다.
- 타인 프로필 페이지 보여주고
- 팔로우 언팔로우를 할 수있다
- 다른거 누르지 말고 나와서 메인 페이지로 돌아옴
- 글 작성 페이지
- 이미지 추가 기능
- 타입 선택시 모델이 필터링 되는 부분 설명
- 태그 검색되는 부분 - 새롭게 추가하는건 분홍색임
- 프로필 페이지가서 생긴 모습 보여주기
- 글 상세 페이지
- 수정 누르면 수정페이지로 이동
- 좋아요
- 글 수정 페이지 수정할 수 있다. 수정하지 않고 수정 버튼 누르기만 하자 (시간걸림)