끄적끄적

프로젝트회고) 뉴스피드기반 앱 - JPA 팔로우기능(Feat.코뮤니티)

hubaek 2024. 10. 28. 02:27

https://github.com/hubaek/co-mu-nity

 

GitHub - hubaek/co-mu-nity

Contribute to hubaek/co-mu-nity development by creating an account on GitHub.

github.com

 

Spring Data JPA를 활용하여 뉴스피드라는 주제로 백엔드 애플리케이션 팀 프로젝트를 진행하기로 하였습니다.

 

저희 팀은 뉴스피드, 커뮤니티 등 컨셉을 생각했을 때 팀원들의 공통 취미인 음악 듣기에서 영감을 얻어 

코딩하는 사람들의 플레이리스트를 공유하는 커뮤니티로 컨셉을 잡았고 프로젝트 이름을 생각하다가

제가 직 커뮤니티를 줄인 코뮤니티를 제안해서 팀원들의 만장일치를 동의를 얻어서 <코뮤니티>가 되었습니다!

 

프로젝트 기간
2024.10.18(금)~2024.10.24(목)

 

프로젝트 목표
Spring을 활용한 CRUD를 중심으로
SNS의 다양한 기술을 개발하고 Github를 사용하여 
협업 커뮤니케이션을 향상

 

기술스택

Java17

SpringBoot 3.3.4 

MySQL

JPA 

Tool : InteliJ, Git, GitHub, ERD Cloud, Postman, Notion, Slack

 

팀구성

이름 역할 담당 기능
김가빈 팀장 JWT, Filter, Password Encoder,
회원가입,로그인
백현욱 부팀장 팔로우, 언팔로우, 팔로잉/팔로워 목록 조회
류지수 팀원 회원조회, 수정, 탈퇴
박정완 팀원 게시글 등록, 조회, 수정, 삭제
이지훈 팀원 댓글 등록, 조회, 수정, 삭제

 

 

와이어프레임

이번 팀 프로젝트 내가 직접 그린 와이어프레임.. (작고 소중해,,)

처음 그려보다보니 프론트 작업은 없고 기간도 4일되는 짧은 프로젝트이다보니, 어느정도 디테일하게 그릴지 어느정도 기능을 넣을지 

scope를 얼마나 잡아야할지 감이 잘 안왔다. (그래서 처음에만 신경 쓰고, 나머지는 간략하게 어느정도 필요한 부분만 그렸음..)

 

ERD

JPA를 사용하면서 MyBatis와 크게 다른 점은 설계단계에서 ERD를 그리기 굉장히 애매하다는 점이였다. 

MyBatis는 ERD설계가 엄청 중요하고 그대로 이용하는데

JPA는 연관관계와 여러 고려사항때문에 테이블 관점이 아닌 Entity 객체 관계라 ERD로 표현하기엔 모호한 부분이 있었다.

그리고 유저와 게시글은 일부러 연관관계를 짓지 않았는데, 그 이유는 도메인 주도 설계의 애그리거트를 참고해서 관계를 설정했다.

연관 도메인을 하나로 묶는 것을 애그리거트라고 표현하는데, 유저와 게시글은 하나의 애그리거트로 보기 어렵고

유저-친구 / 게시글-댓글 두 그룹을 각 애그리거트로 묶어서 이해를 해서 연관관계를 지어주었다.

 

 

핵심 모듈은 총 4가지 - 회원, 게시글, 댓글, 친구(팔로우) 

내가 맡은 모듈은 친구 파트 이다.

 

API 명세서 

친구 파트 API 명세서

친구 API명세서

API명세서는 아직 많이 작성을 안해봐서 request나 response 값을 제대로 표시했는지 잘 모르는 부분이 있긴하다. 

Postman을 많이 써보면서 JSON 데이터가 어떤식으로 오고 가는지 더 공부를 해야할 것 같다.

 

 

기능

팔로우 기능 설계

처음 팔로우 기능을 어떻게 설계해야하나 알아보다가, 팔로우 개념은 여러가지로 해석을 할 수 있어서 정말 다양한 관점이 나왔다.

회원간 팔로우를 하기에 회원테이블 하나로 다대다(Many-To-Many) 관계를 표현 할 수 없어서

회원(Member) 테이블을 연결 해줄 친구(Friend) 테이블을 추가해 OneToMany, ManyToOne 로 양방향관계설정을 하였다.

 

친구 테이블에 회원 fk값이 두개가 들어가는 구조이기 때문에, 처음 이 구조를 이해하면서 설계하기까지 시간이 소요가 되었다.

Friend 엔티티에 회원 두개의 변수명에도 고민이 됐는데 follower, followee / fromMember, toMember 크게 두가지로 표현을 했는데,

처음에 팔로워, 팔로이로 개발을 하다가 개발하는 나조차도 너무 헷갈려서 from,to 형식의 변수명으로 사용하니 

fromMember(요청하는사람), toMember(요청받는사람) 으로 생각을 하니 기능 개발에 조금 더 수월했고 더 설명을 하기에도 쉬워서 

해당 변수명으로 변경했다.

 

FriendController

컨트롤러 계층을 보면서 제일 고민했던건 API 엔드포인트였다.

REST API로 개발을 하는데 follow를 썼는데 해당 단어는 동사여서, following으로 바꾸고 members를 넣을지 말지에 대한 고민이였는데, 조언을 받고 members도 넣는게 괜찮을 것 같다고 해서

/members/{fromMemberId}/following/{toMemberId} 로 팔로우기능의 엔드포인트를 설정하였다.

 처음 JWT 토큰 기능이 개발이 안되어서 fromMemberId를 로그인한 사용자로 가정을 하고, 개발을 우선 진행 하였고

JWT 토큰과 회원가입, 로그인 기능이 개발 완료 후엔 로그인한 사용자와 요청하는 fromMemberId가 일치한지 검증 로직을 추가했다.

 

FriendService

서비스 로직에선 로그인한 사용자와 요청받는 toMemberId 가 일치한지 확인을 해서, 자기자신을 팔로우 할 수 없게 검증을 하고

이미 팔로우 중인지 확인하기 위해, isFollowing 메서드는 만들어 FriendRepository의 쿼리메서드를 활용하여서 검증을 했다.

boolean existsByFromMemberIdAndToMemberId(Long fromMemberId, Long toMemberId);

 


배운 점 & 어려웠던 점

아직 JPA에 대해서 익숙하지 않아서 양방향 연관관계에서 값을 추가하고 조회하는 부분이 헷갈리긴 하는데,

이번엔 Friend 엔티티에 2개의 외래키(fk) 값이 들어가서 더욱 어려웠던 것 같다. 

Member엔티티도 고려하고 다양한 관점에서 생각을 하다보니 많이 익숙해졌고 

협업을 하다보니 Dto도 단순 Request, Response 두가지만 사용할 것이 아닌, 기능별 상황별로 만들어서 반환을 해주는게 사용자가

원하는 값을 얻기 위할 것이라 생각해 팔로우 목록 조회 기능에선 해당 responseDto를 개별로 만들어 반환을 해주었다.

 

개인 기능 개발에선 JPA관련 어려움이 컸지만 팀 협업 관점에선 여러가지 어려운 부분도 컸다.

팀 프로젝트에 경험이 없고, Git에 대한 사용경험도 없는 팀원도 있었기에 초기 설정에서 

기간이 짧아서 application.yml의 DB설정이라던지, Git 브랜치전략, Commit 컨벤션, 다양한 코드컨벤션을 상세하게 정하지 못하고 시작하다보니 개발을 시작할때, 마무리할때 여러가지 통일되지 못한 부분이 있어서 수정하거나 넘어간 부분이 있어서 많이 아쉬웠다.

Git  경험이 없는 팀원이 있었기에, 나도 이번에 Fork를 해서 새롭게 PR이 될때 Merge하는 과정까지를 상세히 정리해서 블로그로 작성을 하면서 개념을 다시 잡았고 그 개념을 잡은 것으로 부팀장으로써 팀원들에게 설명을 해주고 Git관련 오류가 생겼을 때마다 해결을 해주다 보니 더욱 개발에 집중을 할 시간이 부족해졌던 것 같다.

그래도 Git에 문제가 생기거나 원리를 설명을 자세히 해준 덕에 팀원들이 Git에 조금은 쉽게 익숙해졌고 설명을 잘해주고 덕분에 잘 이해를 했다는 말을 들었을 땐 뿌듯한 마음도 들었고, 팀이기때문에 한명에게 문제가 생기면 그 문제가 팀의 시간과 관련되고 팀의 문제라 생각했기에 귀찮다고 생각하지 않고 잘 얘기를 해주었던 것 같다.


개인적으로는 무엇인가를 누군가에게 가르쳐주려면 나 먼저 그 개념에 대해서 제대로 알고 있어야 설명을 할 수 있다고 생각을 하고

그것을 설명해줌으로써 나는 그 개념에 대해서 복습을 하고 한번 더 다져간다고 생각하면 전혀 아깝지 않은 시간이라고 생각한다.

(이해가 잘 되게 설명해준다던지, 잘 이해하고 성장해가는 모습을 보면 뿌듯함 x10)

그래서 이번 팀 프로젝트에선, 팀이기에 다같이 성장을 하는 입장에서 내가 아는 부분에선 적극적으로 공유하고 설명해준 시간이 많았었고 그로인해 짧고 굵게 불태웠던 프로젝트였다.

발표가 끝난 후 모인 팀