<aside> 📌

목차

아키텍처 📐

bscene-server 코드베이스는 핵심 비즈니스 로직과 외부 인프라 사이의 분리를 유지하기 위해 헥사고날 아키텍처(Ports and Adapters) 패턴을 채택합니다. 이 설계는 도메인 계층이 데이터베이스, 메시지 브로커, 외부 API로부터 독립적으로 유지되도록 보장합니다.

High-Level

본 서비스는 확장 가능하고 사용자 친화적인 플랫폼을 목표로 설계되었으며, 유연성과 안정성을 확보하기 위해 마이크로서비스 지향 구조를 따릅니다.

구성 및 모듈

패키지 구조

코드베이스는 두 개의 루트 패키지로 나뉩니다. domain 패키지는 기능 영역(band, stream, session 등)별 비즈니스 로직을 담고, global 패키지는 공유 인프라와 횡단 관심사를 담습니다.

보안 및 인증

인증은 JWT와 OAuth2를 통해 처리됩니다. JwtAuthFilter가 요청을 가로채어 토큰을 검증하고 SecurityContextHolder를 채웁니다.

예외 처리 및 응답 포맷

시스템은 성공과 오류 상태 모두에 대해 통일된 응답 포맷을 사용합니다.

커서 기반 페이지네이션

고성능 무한 스크롤을 지원하기 위해 CursorPage 유틸리티를 통한 커서 기반 페이지네이션을 사용합니다.

구성 요소 설명
items 현재 페이지의 데이터 목록입니다.
nextCursor 다음 요청에 사용할 ID 또는 timestamp입니다.
hasNext 추가 데이터 존재 여부를 나타내는 boolean 값입니다.

인프라 설정

데이터 흐름

요청은 외부 어댑터(Controller)에서 시작되어 Service 계층을 거쳐 Port를 통해 다른 도메인으로 흘러갑니다. 인증 요청의 경우 JwtAuthFilter → CustomUserDetailsService → AuthMember 순으로 사용자 컨텍스트가 매핑됩니다.

flowchart LR
    Client["Client"] --> Filter["JwtAuthFilter"]
    Filter --> UDS["CustomUserDetailsService"]
    UDS --> AuthMember["AuthMember"]
    AuthMember --> Controller["Controller"]
    Controller --> Service["Service"]
    Service --> Port["Port (인터페이스)"]
    Port --> Adapter["Adapter (구현체)"]
    Adapter --> OtherDomain["다른 도메인 / 외부 서비스"]
    Service --> Repository["Repository (JPA)"]

도메인 간 통신

도메인 간 통신은 순환 의존성을 방지하기 위해 엄격하게 통제됩니다.

  1. Event-Driven (Internal): 도메인은 Spring Application Event(예: PostVideoThumbnailRequestedEvent)를 발행하며, 다른 도메인의 리스너가 이를 소비합니다.
  2. Port-Adapter Pattern: 도메인 A가 도메인 B의 데이터나 동작이 필요한 경우 Port(인터페이스)를 정의하고, 도메인 B 또는 전용 어댑터가 이를 구현합니다.