0912 Full-Stack: 스터디룸 기능 개발 (설계부터 구현까지 복습)
✅ 1. 백엔드(BE): 스터디룸 도메인 설계 및 API 구축
- 사용자들이 스터디룸을 생성하고, 참여하며, 관리할 수 있는 핵심 비즈니스 로직과 데이터 모델을 설계하고 RESTful API를 구축했습니다.
➕ 데이터 모델링 및 관계 설정
StudyRoom 엔티티: 스터디룸의 핵심 정보(제목, 설명, 최대 인원)를 관리합니다. User 엔티티와 호스트(Host) 관계를 맺습니다.
RoomParticipant 엔티티: StudyRoom과 User 사이의 다대다(M:N) 관계를 해소하는 중간 테이블 역할을 합니다. 이 엔티티는 단순한 연결을 넘어, 참여자의 역할(ParticipantRole)과 상태(ParticipantStatus) 같은 추가적인 메타데이터를 관리합니다.
- Enum 활용: 역할(HOST, GUEST)과 상태(ACTIVE, INACTIVE)를 열거형(Enum)으로 관리하여, 데이터의 일관성과 가독성을 높였습니다.
➕ 비즈니스 로직 및 API 구현
- CRUD API: 스터디룸의 생성(Create), 조회(Read), 수정(Update), 삭제(Delete)를 위한 기본적인 API 엔드포인트를
StudyRoomController에 구현했습니다.
- 참여 및 나가기 기능:
StudyRoomService 내에 joinRoom과 leaveRoom 메서드를 구현하여, 사용자가 스터디룸에 참여하거나 나갈 때 RoomParticipant 테이블의 데이터를 생성하거나 상태를 변경하는 로직을 처리했습니다.
- 인증 연동: 스터디룸 생성, 참여 등 모든 주요 기능은 JWT 인증을 기반으로 동작합니다. 컨트롤러는
@AuthenticationPrincipal 등을 통해 현재 로그인된 사용자 정보를 가져와, 별도의 userId 필드 없이도 누가 요청했는지 식별하여 처리합니다.
- QueryDSL을 이용한 동적 검색:
StudyRoomRepositoryCustom을 구현하여, QueryDSL을 통해 키워드 검색과 같은 복잡한 동적 쿼리를 타입-세이프하게 작성했습니다. 특히, 스터디룸 목록 조회 시 참여자 수를 함께 조회하는 로직을 포함하여 N+1 문제를 방지하고 성능을 최적화했습니다.
✅ 2. 프론트엔드(FE): 스터디룸 UI 및 전역 상태 관리
- 백엔드에서 구축한 API와 연동하여, 사용자가 스터디룸을 탐색하고 상호작용할 수 있는 사용자 인터페이스와 상태 관리 로직을 구현했습니다.
➕ 컴포넌트 기반 UI 설계
- 컴포넌트 분리: 스터디룸 기능을 여러 개의 재사용 가능한 컴포넌트로 분리하여 설계했습니다.
StudyRoomList: 전체 목록 페이지의 컨테이너 역할.
RoomCard: 개별 스터디룸 정보를 보여주는 카드 UI.
RoomSearchBar: 키워드 검색 기능.
CreateRoomModal: 스터디룸 생성 폼을 담은 모달.
RoomDetail: 스터디룸 상세 정보 및 참여자 목록 표시.
- 사용자 경험(UX) 개선:
- 스켈레톤 UI: 데이터 로딩 중에는 실제 UI의 윤곽선을 보여주는 스켈레톤 컴포넌트를 렌더링하여 사용자가 느끼는 대기 시간을 줄였습니다.
- 무한 스크롤/더보기:
LoadMoreButton과 페이지네이션 로직을 통해 한 번에 모든 데이터를 불러오지 않고, 필요할 때마다 추가 데이터를 로드하여 초기 로딩 성능을 향상시켰습니다.
➕ 전역 상태 관리 (Zustand)
- 문제점: 스터디룸 목록, 생성 모달의 열림 상태 등 여러 컴포넌트에서 공유해야 하는 상태가 많아지면서 Prop Drilling 문제가 발생할 수 있습니다.
- 해결책 (
roomStore): Zustand를 사용하여 스터디룸 관련 상태와 액션을 관리하는 전역 스토어(roomStore)를 생성했습니다.
StudyRoomList 컴포넌트는 이 스토어에서 스터디룸 목록을 가져와 렌더링합니다.
CreateRoomModal에서 스터디룸 생성이 성공하면, 페이지를 새로고침하는 대신 스토어의 상태를 직접 업데이트하여 UI에 즉시 변경 사항을 반영했습니다. 이는 빠르고 부드러운 사용자 경험을 제공합니다.
✅ 3. 프론트엔드(FE): 공통 기능 모듈화 (토스트 알림)
- API 요청의 성공, 실패 등 사용자에게 피드백을 제공해야 하는 상황은 앱 전반에서 발생합니다. 이를 위해 재사용 가능한 토스트 알림(Toast Notification) 시스템을 구축했습니다.
- Context API 활용: 토스트 메시지를 띄우는 함수(
showToast)를 전역적으로 사용할 수 있도록 ToastProvider와 toastContext를 생성했습니다.
- 중앙 관리:
App의 최상단에 ToastProvider를 배치하여, 어떤 컴포넌트에서든 useContext를 통해 showToast 함수를 호출할 수 있게 했습니다.
- 사용 예시: 스터디룸 생성 API 호출이 성공하거나 실패했을 때,
showToast 함수를 호출하여 사용자에게 "방 생성이 완료되었습니다." 또는 "네트워크 오류가 발생했습니다."와 같은 피드백을 즉시 제공했습니다.
📌 요약
- 백엔드는
StudyRoom과 RoomParticipant 엔티티를 중심으로 데이터 모델을 설계하고, QueryDSL을 활용하여 참여자 수를 포함한 동적 검색 API를 구축했습니다. 모든 API는 JWT 인증을 기반으로 동작합니다.
- 프론트엔드는 재사용 가능한 컴포넌트로 UI를 구조화하고, Zustand를 이용한 전역 상태 관리를 통해 컴포넌트 간 데이터 흐름을 효율적으로 처리했습니다.
- 사용자 경험을 향상시키기 위해 스켈레온 UI, 페이지네이션, 그리고 Context API 기반의 전역 토스트 알림과 같은 공통 모듈을 구현하여 애플리케이션의 완성도를 높였습니다.