범위: 프론트 개발환경 구성, 백엔드 데이터 확장, 리뷰 리스트 기능 구현, CORS 해결
1. 프론트엔드 개발환경 구성
BE 기본작업이 어느정도 완성되어서 FE 또한 작업이 필요했고 제가 맡아 개발환경 세팅을 시작하였습니다.
이전까지는 단순히 구조만 짜두고 페이지 파일만 만들어놓은 상태였는데, 본격적으로 개발을 시작하면서 FE는 너무 오랜만이기도 하고 해서 많은 고민과 실험이 있었습니다..!
초기 삽질 요약
- CRA(Create React App)보다 더 가볍고 빠른 환경을 만들고 싶어서 Vite + React로 구성
- TailwindCSS도 도입해보려 했지만 설정 충돌, PostCSS 관련 오류, 예상치 못한 스타일 깨짐 등으로 시간만 소비함 → 결국 순수 CSS로 회귀....
- 디렉토리 구조도 pages, components, api, assets 등으로 재정비
그 결과, 컴포넌트 기반 + 라우터 구조가 명확한 환경을 깔끔하게 정비할 수 있었습니다.
2. 주요 페이지 초기 구성
BottomTab을 고정 레이아웃으로 두고, 주요 화면은 다음과 같이 설계하였습니다.
- HomePage: 기본 홈, 추후 추천 기반 리스트
- SearchPage: 검색 필터 화면
- ListPage: 내가 저장한 맛집 리스트
- MyPage: 계정 관리 및 설정
모든 라우팅은 react-router-dom의 Routes 기반으로 연결했고, BottomTab은 항상 하단에 고정되도록 CSS 구조를 설계하였습니다. 현재는 ListPage만 BE와 연결이 되어있고, 나머지 페이지들은 데이터가 모두 하드코딩 되어있는 상태입니다.
3. ListPage UI 구현
가장 먼저 만들기로 한 기능은 내 맛집 리스트 페이지 입니다.
처음엔 단순히 리스트만 보여주면 될 줄 알았지만, 생각보다 고려해야 할 요소가 많았습니다,,
포함된 요소:
- 검색창 UI
- 평점/카테고리 필터 버튼
- 리뷰 목록 카드 형태 렌더링
- 하단 + 추가하기 버튼
Tailwind 없이 순수 CSS로 작업했기 때문에 클래스 단위로 스타일을 잡아가며 레이아웃을 조절했고,
썸네일 이미지/텍스트/평점이 좌우로 자연스럽게 배치되도록 flex 중심의 구조를 적용하였습니다..(GPT의 도움!)
4. 백엔드 구조 확장 – restaurant.imageUrl 추가
프론트에서 썸네일 이미지를 보여주기 위해서는 레스토랑 정보에 이미지 URL이 필요했고,
그러나 기존 restaurant 테이블엔 imageUrl 필드가 존재하지 않았기 때문에 다음 작업을 수행하였습니다.
- Restaurant 엔티티에 imageUrl 필드 추가 (TEXT 타입)
- RestaurantRequest, RestaurantResponse DTO 수정
- POST, PUT API에서 해당 필드를 받아 저장할 수 있도록 서비스 로직 수정
- DB에 직접 컬럼 추가 (ALTER TABLE restaurant ADD COLUMN image_url TEXT;)
처음 DB를 설계할 때, 나름대로 시나리오를 생각하고 짰는데 벌써 수정이 필요하다니.. 아직 많이 부족한가봅니다!
5. 리뷰 응답에 레스토랑 정보 포함시키기
프론트에서 "내가 남긴 리뷰" 리스트를 제대로 보여주기 위해서는
단순히 리뷰 정보만이 아니라 리뷰에 연결된 음식점 정보도 함께 필요했습니다.
이를 위해 기존 ReviewResponse DTO에 다음 필드를 추가하였습니다.
- restaurantName
- restaurantImageUrl
- restaurantAvgRating
서비스 계층에서는 review.getRestaurant()를 통해 위 정보를 함께 추출했고,
결과적으로 클라이언트는 하나의 API로 모든 정보를 받아올 수 있게 되었습니다.
6. API 추가 – /api/reviews/user/{userId}
기존의 /api/reviews는 전체 리뷰를 불러오는 용도였기 때문에,
특정 단일 사용자의 리뷰만 불러오는 전용 API를 새로 만들었습니다.
해당 유저의 리뷰 중 deleted = 0 조건만 걸어 반환하며,
각 리뷰마다 레스토랑의 name, 이미지, 평점이 포함됩니다.
7. CORS, WebConfig
프론트와 백엔드 서버가 각각 localhost:5173, localhost:8080으로 나뉘어 있다 보니
당연하게도 CORS(Cross-Origin Resource Sharing) 오류가 발생하였습니다.
❌ "No 'Access-Control-Allow-Origin' header is present..."
해결 방법:
- WebConfig.java 파일을 새로 생성하고,
CorsRegistry를 통해 개발용 포트(5173)를 명시적으로 허용 - 처음엔 잘 안 먹혀서 삽질했지만, 결국 원인은 WebConfig 위치가 루트에 있었던 것
→ 반드시 src/main/java/com/michelin/config 안에 넣고 패키지 선언도 정확히 해야 Spring이 인식
8. 프론트 API 연동 및 렌더링 완료
이제 ListPage.jsx에서 getMyReviews(userId) 함수를 통해 해당 유저의 리뷰를 요청하고,
응답으로 받은 데이터들을 카드 형식으로 렌더링함으로써
“내가 남긴 리뷰를 기반으로 한 맛집 리스트” 기능이 완성되었습니다.
Git 푸시 및 정리
- 기능별로 커밋 메시지 정리 (feat: 사용자 리뷰 API 구현, feat: 내 리스트 연동, 등)
- 백엔드는 인규의 GitHub에도 동시 push 완료
- 다음부터는 브랜치 분기 및 PR 기반 협업 구조도 적용해볼 계획
마무리 & 다음 할 일
- 리뷰 등록 기능 연동 (POST)
- 평점/카테고리 필터 기능
- 로그인 / 사용자 인증 추가
- 맛집 상세 정보 페이지 구성
'Project > 나혼자 미슐랭' 카테고리의 다른 글
나혼자 미슐랭 개발일지 #5 – 마이페이지 및 프로필 수정 기능 구현 (0) | 2025.05.17 |
---|---|
나혼자 미슐랭 개발일지 #4 – 리뷰 작성과 리스트 페이지 완성(무한스크롤 & 필터) (3) | 2025.05.15 |
나혼자 미슐랭 개발일지 #2 – User, Restaurant, Review CRUD 개발완료 (0) | 2025.05.10 |
나혼자 미슐랭 개발일지 #1 - 개발환경 세팅 & DB 연결 (0) | 2025.05.05 |
나혼자 미슐랭 – DB 설계 정리 (0) | 2025.04.29 |