BindProject

[Backend] BFF 구현 하기 앞서 구상 및 정리

dding-shark 2025. 6. 17. 21:10
728x90

BFF (Backend for Frontend) 설계와 구현 전략: 실전 사례 기반 정리

서비스를 MSA로 구성할 때, BFF는 클라이언트와 내부 서비스 간 연결 고리이자 최적화된 API 응답을 제공하는 핵심 계층입니다. 이번 글에서는 BFF를 어떻게 구성하고, 어떤 기술 스택과 구조를 선택해야 하는지 실제 설계와 대화를 기반으로 정리합니다.


설계 전 이해해야 할 핵심 질문

  • BFF는 단순 proxy인가, 아니면 API 응답을 조합하는 조립자(Facade)인가?
  • 인증은 어디서 처리하는가? Gateway에서 JWT를 디코딩할까, Auth 서비스에 위임할까?
  • 병렬 호출이 필요한가? WebFlux가 진짜 필요한가?
  • Kafka 이벤트 시스템과 BFF의 역할은 어떻게 나뉘는가?

프로젝트 구조 설계

project-root/
├── application/
│   └── bff/                  # Gateway + 클라이언트 맞춤 응답 조립
├── service/
│   ├── auth/                 # 인증 관련 도메인
│   └── user/                 # 사용자 관련 도메인
└── infra/
    └── public/               # 공통 기술 모듈 (event, outbox, error 등)
  • bff: 클라이언트 전용 API, 내부 도메인 서비스 호출/조합 담당
  • public: 재사용 가능한 cross-cutting concerns 담당
  • service: 각 도메인 서비스 (Auth, User 등)

BFF 기능 구성 예시 (Dashboard API)

1. 컨트롤러 계층

@RestController
@RequestMapping("/me")
@RequiredArgsConstructor
public class DashboardController {

    private final DashboardFacade dashboardFacade;

    @GetMapping("/dashboard")
    public DashboardResponse getDashboard(@AuthenticationPrincipal JwtUser user) {
        return dashboardFacade.assembleDashboard(user.getUserId());
    }
}

2. 조합/오케스트레이션 계층

@Service
@RequiredArgsConstructor
public class DashboardFacade {

    private final UserServiceClient userServiceClient;
    private final ActivityServiceClient activityServiceClient;

    public DashboardResponse assembleDashboard(Long userId) {
        UserDto user = userServiceClient.getUser(userId);
        List<ActivityDto> activities = activityServiceClient.getRecentActivities(userId);
        return new DashboardResponse(user, activities);
    }
}

WebFlux를 써야 할까?

쓰는 게 좋을 때

  • 대시보드처럼 여러 서비스에 병렬 호출 후 응답 조합할 때
  • 응답 속도가 매우 중요한 모바일 초기 진입 API
  • 내부 서비스도 reactive하게 구성되어 있을 때

굳이 안 써도 될 때

  • 호출 대상이 1~2개고, 동기 처리로 충분할 때
  • 팀에 WebFlux 경험이 부족할 때
  • downstream 서비스가 blocking I/O일 때

Kafka 이벤트 시스템과 역할 분리

WebFlux 병렬 호출 Kafka 이벤트 처리
요청 시 동기 호출 도메인 이벤트 기반 비동기 처리
즉각 응답이 필요 후속 처리는 늦어져도 됨
응답 조합 및 클라이언트 전용 API 목적 서비스 간 decoupling 및 후처리
  • 로그인: WebFlux로 빠른 응답 + Kafka로 로그인 로그 기록
  • 회원가입: DB 저장 후 Kafka로 UserCreated 이벤트 전파

인증 전략: JWT + Redis 블랙리스트

  • JWT로 사용자 인증 (stateless)
  • Redis는 로그아웃/차단된 토큰만 블랙리스트로 저장
  • 로그인 응답은 빠르고, 로그아웃 시 Redis에 토큰을 저장하여 차단
SET blacklist:{token} "" EX {TTL}
→ 로그인 시 Redis에서 조회하여 유효성 확인

결론

  • BFF는 단순 gateway가 아니다. 클라이언트 전용 API 조립자다.
  • WebFlux는 병렬 호출 최적화에만 전략적으로 써야 한다.
  • Kafka는 BFF 응답 이후의 후속 작업 decoupling에 적합하다.
  • JWT 인증 + Redis 블랙리스트는 실전에서 가장 안정적인 하이브리드 전략이다.

728x90