TIL - 20250901

juni·2025년 9월 1일

TIL

목록 보기
112/316

0901 Full-Stack Event App: Spring Boot & React Integration


✅ 1. 백엔드(BE): Spring Boot 기반의 REST API 구축

  • 애플리케이션의 핵심 데이터와 비즈니스 로직을 처리하는 서버 API를 구축했습니다. 클라이언트(React)는 이 API를 통해 데이터를 요청하고 조작합니다.

➕ 주요 개념

  1. RESTful API 설계: 이벤트(Event)라는 자원(Resource)을 중심으로, HTTP 메서드(GET, POST, PUT, DELETE)를 사용하여 직관적인 API 엔드포인트를 설계했습니다.

    • GET /api/events: 전체 이벤트 목록 조회
    • GET /api/events/{id}: 단일 이벤트 상세 조회
    • POST /api/events: 새 이벤트 생성
    • PUT /api/events/{id}: 이벤트 수정
    • DELETE /api/events/{id}: 이벤트 삭제
  2. DTO (Data Transfer Object): 데이터베이스와 직접 연결된 엔티티(Entity)를 클라이언트에 그대로 노출하는 대신, API의 각 목적에 맞는 DTO를 만들어 사용했습니다. 이를 통해 API 스펙을 안정적으로 유지하고, 민감한 정보를 숨기며, 필요한 데이터만 선택적으로 전달할 수 있습니다.

  3. 전역 CORS 설정: 브라우저의 보안 정책상 다른 출처(Origin)의 리소스를 요청하는 것은 기본적으로 차단됩니다. React 개발 서버(localhost:3000)가 Spring API 서버(localhost:9000)에 데이터를 요청할 수 있도록, Spring Boot에 전역 CORS(Cross-Origin Resource Sharing) 설정을 추가하여 특정 출처의 요청을 허용했습니다.


✅ 2. 프론트엔드(FE): React Router를 이용한 SPA 구조화

  • 페이지를 새로고침하지 않고도 URL에 따라 다른 화면을 보여주는 싱글 페이지 애플리케이션(SPA)의 골격을 React Router를 사용하여 구축했습니다.

➕ 주요 개념

  1. 라우터 기본 설정: createBrowserRouter를 사용하여 애플리케이션의 전체 라우팅 구조를 객체 형태로 정의했습니다. 이를 통해 URL 경로와 렌더링할 컴포넌트를 중앙에서 관리합니다.

  2. 레이아웃과 중첩 라우팅:

    • 여러 페이지에서 공통적으로 사용되는 헤더, 푸터 등을 루트 레이아웃(Root Layout)으로 만들었습니다.
    • 이벤트 관련 페이지들(목록, 상세, 생성)에서 공통으로 사용되는 네비게이션 바 등은 이벤트 레이아웃(Events Layout)으로 분리했습니다.
    • <Outlet /> 컴포넌트를 사용하여, 부모 레이아웃의 특정 위치에 자식 라우트 컴포넌트가 렌더링되도록 하는 중첩 라우팅 구조를 구현했습니다. 이는 코드의 중복을 획기적으로 줄여줍니다.
  3. 커스텀 에러 페이지: errorElement 설정을 통해 존재하지 않는 경로로 접근하거나 데이터 로딩 중 에러가 발생했을 때, 사용자에게 친화적인 에러 페이지를 보여주도록 처리하여 애플리케이션의 안정성을 높였습니다.


✅ 3. 데이터 연동 및 loader를 통한 성능 최적화

  • React 애플리케이션이 Spring API 서버와 통신하여 데이터를 가져오고, 이를 화면에 렌더링하는 과정을 구현하고 최적화했습니다.

➕ 데이터 페칭(Fetching)의 진화

  1. 초기 방식 (useEffect): 컴포넌트가 렌더링된 후, useEffect Hook 안에서 fetch를 사용하여 API를 호출하고, 받아온 데이터로 상태(state)를 업데이트하여 화면을 다시 렌더링하는 방식을 사용했습니다.

  2. 개선된 방식 (React Router loader):

    • 개념: loader는 React Router v6.4부터 도입된 강력한 기능으로, 컴포넌트가 렌더링되기 전에 데이터를 미리 가져오는 함수입니다.
    • 동작 방식: 라우트 설정에 loader 함수를 정의해두면, 해당 경로로 이동할 때 React Router가 이 함수를 먼저 실행합니다. loader가 데이터를 모두 가져오면, 그 데이터를 컴포넌트에 prop처럼 전달하여 렌더링을 시작합니다.
    • 장점: 컴포넌트 내부에서 로딩 상태를 관리할 필요가 줄어들고, 데이터가 준비된 상태에서 컴포넌트가 렌더링되므로 사용자 경험(UX)이 크게 향상됩니다. useLoaderData Hook을 사용하여 컴포넌트 내에서 loader가 반환한 데이터에 쉽게 접근할 수 있습니다.

✅ 4. Full-Stack CRUD 사이클 완성

  • 위의 개념들을 종합하여 사용자가 이벤트를 생성, 조회, 수정, 삭제할 수 있는 완전한 기능 사이클을 구현했습니다.

  • 흐름:

    1. [FE] 사용자가 이벤트 생성 폼을 작성하고 제출합니다.
    2. [FE] POST /api/events API를 호출하여 데이터를 서버에 전송합니다.
    3. [BE] Spring 컨트롤러가 요청을 받아 DTO로 변환하고, 서비스 로직을 통해 데이터를 DB에 저장합니다.
    4. [FE] 이벤트 목록 페이지나 상세 페이지에서 loaderGET API를 호출하여 데이터를 미리 가져옵니다.
    5. [FE] 가져온 데이터를 화면에 렌더링합니다. (수정/삭제도 유사한 흐름으로 동작)

📌 요약

  • 백엔드Spring Boot를 사용하여 안정적인 RESTful API를 구축했으며, DTO로 데이터 전송을 표준화하고 CORS로 외부 요청을 허용했습니다.
  • 프론트엔드React Router중첩 레이아웃을 통해 재사용 가능한 UI 구조를 만들었습니다.
  • 데이터 연동 방식은 useEffect에서 React Router의 loader로 발전시켜, 렌더링 전에 데이터를 가져오는 최적화된 패턴을 적용했습니다.
  • 이러한 과정을 통해 관심사가 명확히 분리되고, 각자의 역할에 충실하며, 효율적으로 통신하는 현대적인 Full-Stack 애플리케이션의 구조를 완성했습니다.

0개의 댓글