Skip to main content

프론트엔드 아키텍처 상세

이 문서는 프론트엔드 애플리케이션의 상세 폴더 구조와 각 디렉토리의 역할, 그리고 주요 기술 전략에 대해 설명합니다.


1. 폴더 구조 (Feature-based)

프로젝트는 기능 중심(Feature-based) 아키텍처를 따릅니다. 이는 관련된 기능의 코드들을 하나의 폴더에 모아 응집도를 높이고, 다른 기능과의 결합도를 낮추기 위함입니다.

src/
├── app/ # Next.js의 핵심 라우팅 폴더 (페이지 및 레이아웃)
├── components/ # 공용 컴포넌트 (Atomic Design)
│ └── ui/ # Button, Input, Modal 등 순수 UI 컴포넌트
├── features/ # ✨ 각 기능별 폴더를 분리하는 핵심 영역
│ ├── auth/ # 인증(로그인, 로그아웃) 관련 기능
│ │ ├── api/ # 인증 관련 API 호출 함수 (예: login, getNonce)
│ │ ├── components/ # 인증 기능에서만 사용하는 컴포넌트 (예: ConnectWalletButton)
│ │ └── hooks/ # 인증 관련 커스텀 훅 (예: useAuth)
│ └── ... # 향후 추가될 기능들 (gallery, payment 등)
├── hooks/ # 여러 기능에서 공통으로 사용하는 커스텀 훅
├── lib/ # 외부 라이브러리 설정, 유틸리티 함수 등
│ └── apiClient.ts # 중앙화된 Axios 인스턴스
└── providers/ # Context API, React-Query 등 전역 상태 제공자

2. 상태 관리 (State Management)

상태는 서버 상태와 클라이언트 상태로 명확히 구분하여 관리합니다.

2.1. 서버 상태: TanStack Query (React-Query)

  • 역할: API를 통해 받아오는 모든 데이터(예: 갤러리 목록, 사용자 프로필 등)를 관리합니다.
  • 사용 이유:
    • 데이터 페칭, 캐싱, 동기화, 재시도 등 복잡한 로직을 매우 간결한 코드로 처리할 수 있습니다.
    • 로딩 및 에러 상태를 자동으로 관리하여 UI 개발 생산성을 높입니다.
    • Stale-While-Revalidate 전략을 통해 사용자 경험을 향상시킵니다.
  • 구현: providers/ReactQueryProvider.tsx에서 클라이언트를 생성하고, app/layout.tsx에서 최상위 컴포넌트를 감싸는 형태로 적용합니다.

2.2. 클라이언트 상태: React Context API

  • 역할: 서버와 무관하게 클라이언트에서만 유지되는 전역 상태를 관리합니다. (예: 사용자의 지갑 연결 상태, 주소)
  • 사용 이유:
    • 외부 라이브러리 의존 없이 React의 내장 기능만으로 간단한 전역 상태를 관리할 수 있습니다.
    • 서버 상태와 명확히 분리되어 코드의 복잡성을 줄입니다.
  • 구현: providers/Web3Provider.tsx와 같이 기능별 Provider를 생성하고, app/layout.tsx에서 적용합니다.
  • 로그인 상태: isLoggedIn과 같은 로그인 상태는 useAuth 훅의 userProfile 쿼리 결과를 통해 서버로부터 확인합니다.

3. 데이터 페칭 (Data Fetching)

모든 백엔드 API 요청은 중앙화된 apiClient를 통해 이루어집니다.

  • 구현: lib/apiClient.ts 파일에 axios 라이브러리를 사용하여 인스턴스를 생성합니다.
  • 주요 설정:
    • baseURL: 백엔드 API 서버의 기본 주소를 설정합니다.
    • timeout: 요청 시간 초과를 설정합니다.
    • withCredentials: true: 쿠키를 포함한 요청을 보낼 수 있도록 설정합니다.
    • 인터셉터(Interceptors):
      • 요청 인터셉터: (현재는 HttpOnly 쿠키 사용으로 인해 필요 없음) 모든 요청이 보내지기 전에, 로컬 스토리지 등에서 JWT(Access Token)를 읽어와 Authorization 헤더에 자동으로 추가하는 로직을 구현합니다.
      • 응답 인터셉터: API 응답 에러(예: 401 Unauthorized)를 공통으로 처리하는 로직을 구현합니다.

3.1. JWT 저장 방식 (보안 고려사항)

JWT(Access Token)는 **HttpOnly 속성이 설정된 쿠키(Cookie)**에 저장됩니다. 이는 XSS(Cross-Site Scripting) 공격으로부터 토큰을 보호하기 위한 보안 강화 조치입니다. HttpOnly 쿠키는 JavaScript에서 접근할 수 없으므로, 클라이언트 측 코드에서 토큰을 직접 읽거나 수정할 수 없습니다.


4. 경로 관리 (Path Alias)

tsconfig.jsonpaths 설정을 사용하여 절대 경로 임포트를 사용합니다.

  • 설정: "@/*": ["./src/*"]
  • 사용 예시: import { Button } from '@/components/ui/Button';
  • 이점: 파일의 위치가 변경되어도 import 경로를 수정할 필요가 없어, 리팩토링 시 편의성과 코드의 가독성을 크게 향상시킵니다.