BindProject

[Backend] bff 구현하기 1편. 배경 및 아키텍처 선택 과정

dding-shark 2025. 6. 26. 15:58
728x90

1편. 배경 및 아키텍처 선택 과정

도입 배경

스타트업 초기에 빠르게 기능을 개발하고 운영 부담을 최소화하는 것은 가장 중요한 목표였습니다.
초창기 서비스는 사용자 인증, 프로필 조회, 주문 내역 확인, 알림 제공 정도의 단순한 기능을 요구했지만, 점차 사용자 증가와 함께 동시성, 장애 격리, 로깅·모니터링, 권한 검증 같은 공통 관심사가 대두되었습니다.
이때 두 가지 접근을 놓고 고민했습니다.

요구사항 정리

  • 인증·인가: JWT 기반 인증, 권한 검증 로직이 필요
  • 오케스트레이션: 여러 서비스 호출을 병렬로 조합해 클라이언트에 반환
  • 공통 정책: 회로 차단, 리트라이, 로깅, 메트릭 수집
  • 운영 효율: 가능한 한 애플리케이션 수를 줄이고 배포·모니터링을 단순화
  • 확장성: 기능 추가 시 최소한의 코드 변경으로 대응

비교 대상

항목 Spring Cloud Gateway + BFF 분리 Spring WebFlux 단일 앱
서비스 수 Gateway, BFF 두 개 하나의 WebFlux 앱
공통 관심사 처리 Gateway가 자동 제공 WebFilter·리액터 필터 직접 구현
오케스트레이션 및 비즈니스 로직 BFF에서만 구현 동일 앱 내에서 RouterFunction/Controller 구현
배포·운영 복잡도 두 애플리케이션 배포·모니터링 하나의 애플리케이션만 관리
초기 학습 곡선 Spring Cloud 설정 학습 필요 WebFlux·리액터 API 학습 필요

Spring Cloud Gateway + BFF 장단점

  • 장점
    • 인증, 인가, 회로 차단, 리트라이, OAuth2, 로깅 플러그인 완전 통합
    • Gateway 설정만으로 공통 필터 체인 구성 가능
    • BFF는 오로지 비즈니스 로직에 집중
  • 단점
    • Gateway와 BFF 두 개를 운영해야 함
    • 두 모듈 간 네트워크 지연 및 헤더 전달 체인 관리 필요
    • 스타트업 초기에는 인프라 관리 오버헤드가 큼

Spring WebFlux 단일 앱 장단점

  • 장점
    • Netty 기반 논블로킹 처리로 높은 동시성
    • WebFilter로 인증·인가, RouterFunction 또는 @Controller로 라우팅·오케스트레이션을 하나의 코드베이스에서 처리
    • 배포 대상이 하나로 줄어들어 운영·모니터링 부담 감소
  • 단점
    • Circuit Breaker, Rate Limiter, 메트릭 수집, 분산 트레이싱 등을 수동 설정해야 함
    • WebFlux와 Reactor API 학습 곡선 존재
    • 공통 정책 변경 시 코드 수정 범위가 넓어질 수 있음

의사결정 포인트

  1. 운영 부담 최소화: 애플리케이션 수를 하나로 줄이면 모니터링·로그 관리 포인트 감소
  2. 개발 속도: 공통 정책을 코드로 구현하더라도 스타트업 규모에서는 초기 투자 대비 이득이 크다고 판단
  3. 유연성: WebFlux 하나로 모든 라우팅과 오케스트레이션을 직접 제어하면서 빠른 피드백 사이클 확보

구현 개요

  1. application.yml
    • 서비스 URL, JWK Set URI, Circuit Breaker 설정 등 한 곳에 관리
  2. JwtAuthFilter
    • WebFilter로 Authorization 헤더에서 JWT 추출·검증
    • Claims를 HTTP 헤더(X-User-Id, X-User-Roles)로 주입
  3. RouterFunction / @RestController
    • 함수형 또는 어노테이션 기반 라우팅으로 모든 엔드포인트 정의
  4. WebClient Bean
    • 서비스별 baseUrl, Resilience4j CircuitBreaker 필터 적용
  5. Reactor 조합
    • Mono.zip, Flux.collectList로 병렬 서비스 호출 후 DTO 조합

테스트 전략

  • WebFilter 단위 테스트: 정상 토큰, 만료 토큰, 잘못된 서명 토큰 시나리오
  • 라우팅 핸들러 테스트: WebTestClient로 HTTP 경로 매핑 및 헤더 전달 검증
  • WebClient 호출 목업: 서비스 장애 및 정상 응답 시나리오 검증
  • 통합 테스트: 인증부터 응답 조합까지 전체 플로우 검증

회고 및 확장 가능성

단일 WebFlux 앱 구조로 초기 개발과 운영 부담을 크게 줄였습니다.
다만 공통 정책이 코드 곳곳에 분산되므로 서비스 규모가 커지면 Config Server, Eureka 기반 서비스 디스커버리, API Gateway 재도입을 고려해야 합니다.
차기 과제로 OpenAPI Generator 자동 계약 코드 생성과 GraphQL 전환을 검토 중입니다.

728x90