6.5 KiB
6.5 KiB
04. 아키텍처 패턴
ST 앱이 채택한 FSD(Feature-Sliced Design) 아키텍처 및 전체 데이터 흐름을 설명합니다.
1. FSD(Feature-Sliced Design) 아키텍처
FSD는 레이어(Layer) 계층 간 단방향 의존성을 강제하는 프론트엔드 아키텍처 방법론입니다.
"하위 레이어는 상위 레이어를 참조할 수 없다" 는 규칙이 핵심입니다.
┌─────────────────────────────────────────┐
│ app / pages (라우팅) │ ← 최상위 (조합)
├─────────────────────────────────────────┤
│ components (업무 UI) │
├─────────────────────────────────────────┤
│ entities (도메인 엔티티) │ ← API 서비스 + 타입
├─────────────────────────────────────────┤
│ shared (공통 기반) │ ← 최하위 (재사용)
└─────────────────────────────────────────┘
각 레이어는 내부적으로 슬라이스(Slice)와 세그먼트(Segment)로 세분화됩니다.
레이어/슬라이스/세그먼트
예시: entities/statistics/api/
entities/statistics/model/
2. 레이어별 역할과 의존성 방향
🔷 shared - 공통 기반 레이어
- 역할: 모든 레이어에서 공유 가능한 순수 유틸리티, API 클라이언트, 타입, 훅, 스토어 정의
- 의존성: 다른 레이어를 참조하지 않음 (최하위)
- 주요 내용:
client.ts,use-mutation-wrapper, Zustand 스토어 정의, 환경변수 설정
🔶 entities - 비즈니스 도메인 레이어
- 역할: 하나의 비즈니스 도메인(auth, menu, statistics 등)을 API 서비스와 타입으로 캡슐화
- 의존성:
shared만 참조 가능 - 주요 내용: API 서비스 함수, 요청/응답 인터페이스 타입
🟩 components - UI 컴포넌트 레이어
- 역할: 업무 화면을 구성하는 React 컴포넌트. 서버 데이터 페칭 로직 포함
- 의존성:
shared,entities참조 가능 - 주요 내용: 화면별 컴포넌트, module 공통 컴포넌트(DataGrid, SearchForm 등)
🟦 app / pages - 라우팅 레이어
- 역할: Next.js 라우팅 연결. 컴포넌트를 조합하여 최종 페이지 구성
- 의존성: 모든 하위 레이어 참조 가능
3. 미들웨어 기반 API 프록시 아키텍처
클라이언트가 백엔드 API를 직접 호출하지 않고 Next.js Middleware를 통해 프록시합니다.
Browser
│
│ 요청: /server/st-management-service/...
▼
Next.js Middleware (middleware.ts)
│
├─ /server/st-management-service/* → ST 전용 백엔드 서버
├─ /server/st-input-service/* → ST 입력 서비스 서버
├─ /server/* → 일반 백엔드 서버 (Spring Boot 등)
├─ /attach-service/* → 파일 첨부 서비스
└─ /api/link/* → 외부 링크 백엔드 API
핵심 동작:
- 요청 URL 경로(
pathname)를 패턴 매칭 - 쿠키에서 JWT 토큰(
CLAIM_NAME)과 사용자 ID(AUTH_USER_ID) 추출 - 해당 값을 요청 헤더에 주입 후 실제 백엔드로 URL 재작성(
NextResponse.rewrite) - 응답에 CSP 보안 헤더 추가
4. 멀티 백엔드 분리 구조
┌─────────────────────────────────────────────────────────┐
│ ST 프론트엔드 앱 │
│ │
│ src/shared/api/client.ts │
│ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ client │ │ stClient │ │
│ │ (일반 API) │ │ (ST 서비스 전용 API) │ │
│ └──────────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │
▼ ▼
일반 백엔드 (Spring) ST 전용 백엔드 서비스
BASE_URL ST_SERVICE_BASE_URL
5. 컴포넌트 데이터 흐름
통계 화면을 예시로 데이터 흐름을 설명합니다.
app/(with-base-layout)/... ← 라우팅 진입
│
▼
components/statistics/input/
StatsInputStatusInp.tsx ← 페이지 컴포넌트
│
├── [검색 이벤트] handleSearch()
│ │
│ ▼
│ entities/statistics/api/
│ statistics-input-status-service.ts ← API 서비스
│ │
│ ▼
│ shared/api/client.ts (stClient) ← Axios 인스턴스
│ │
│ ▼
│ middleware.ts ← Next.js 프록시
│ │
│ ▼
│ ST 백엔드 API 서버
│
├── [상태 관리] useSWR / useTabStore / useAlertStore
│
└── [렌더링] SearchForm + DataGrid(RealGrid) + 버튼
6. 탭 기반 네비게이션 패턴
ST 앱은 메뉴를 클릭하면 새 페이지로 이동하는 것이 아니라, 탭(Tab)을 추가하는 방식으로 내비게이션이 동작합니다.
메뉴 클릭
│
▼
useTabStore.addTab()
│
├── 이미 열린 탭이면 → 해당 탭 활성화 전환만
└── 새 탭이면 → 탭 목록에 추가 (최대 10개 제한)
│
▼
activeTabId 변경
│
▼
각 화면 컴포넌트:
useEffect([activeTabId]) → 탭 포커스 감지 → mutate() 데이터 갱신