엔드포인트 재사용과 BFF
- 갑자기 이 생각이 문득 들었다. ‘다른 화면에서 동일한 엔드포인트를 사용해서 화면에 노출시킬 수 있다면 그 방식이 구현하기 더 편리하지 않나?’
- 하지만 이 생각은 치명적인 위협이 될 수 있다.
-
- 트래픽과 성능 (Network & Payload Overhead)
- 불필요한 오버헤드(Over fetching) : B화면에서는 A, B 필드만 필요한데, A 화면용 엔드포인트를 그대로 써서 A~Z까지 26개 필드를 가져오면 네트워크 대역폭을 쓸데없이 낭비한다.
- 모바일 환경 악영향: 모바일 웹이나 앱 환경에서는 몇 KB의 차이가 로딩 속도와 LCP(Largest Contentful Paint) 지표, 사용자의 데이터 소모량에 직격탄을 줍니다.
-
- 유지보수와 커플링 (Coupling & Side Effects)
- 하나를 고쳤는데, 엉뚱한 화면이 터진다 : A 화면의 요구사항이 바뀌어서 백엔드의 기존 엔드포인트 응답 구조나 로직을 변경했다. 이떄 이 엔드포인트를 B, C 화면에서도 공유하고 있었다면 A 화면을 수정하다가 B, C 화면에 장애가 나는 강한 결합(Tight Coupling) 문제가 생긴다.
- 의도 파악 문제 : 백엔드 코드의 로그를 볼 때도 화면과 목적이 명확한 엔드포인트는 추적이 쉬운 반면, 하나의 엔드포인트를 사방에서 공유해서 사용하면 로그 추적에 어려움을 겪을 수 있다.
-
- 보안과 데이터 노출 (Security Issue)
- 개인정보 유출 우려 : 클라이언트 단에서의 필요한 필드만 선택하는 방식은 브라우저 개발자 도구에서 열어볼 수 있기 때문에 작성자의 개인정보(전화번호, 주민번호 등)가 노출될 수 있다.
- 예외적으로 ‘재사용’하는 경우도 물론 있다.
-
- 완전한 동일 도메인·엔티티 CRUD인 경우 : A 화면이 ‘상품 상세 페이지’고, B 화면이 ‘상품 편집 모달’이라서 화면의 목적과 다루는 데이터가 100% 동일할 때
-
- GraphQL을 사용하는 경우 : GraphQL은 예외적으로 클라이언트가 필요한 필드만 쿼리로 요청하기 때문에 Over fetching과 Tight Coupling 문제를 해결할 수 있다.
-
-
그렇다면 타협안(Best Practice)은 뭘까?
-
- 비즈니스 로직(Service Layer)는 재사용하되, Controller(API)는 분리한다.
- ex. /api/v1/screen-a/data , /api/v1/screen-b/data 처럼 분리해서 각 화면에 맞는 DTO만 반환.
BFF(Backend for Frontend)란?
- BFF는 말 그대로 프론트엔드를 위해 존재하는 전용 백엔드 레이어를 의미한다.
- Next.js 환경에서 BFF를 구축하는 것은 브라우저가 직접 메인 백엔드와 통신하지 않고, Next.js 서버(Server Components 또는 Route Handler)를 중간 다리(Proxy/Gateway)로 두고 통신하는 구조다.
- 전통 아키텍처와 Next.js BFF 아키텍처의 비교
- 기존(전통) 방식
- 브라우저가 직접 메인 백엔드 API를 호출
- 응답 데이터를 프론트엔드 브라우저(JS)에서 직접 정제하고 가공
- Next.js BFF 방식
- 브라우저는 Next.js의 Route Handler나 Server Action을 호출
- Next.js 서버가 메인 백엔드로 요청을 전달하고, 받은 응답을 화면에 맞게 가공한 뒤 브라우저로 리턴
- 기존(전통) 방식
방식이 다른 건 알겠는데, 그러면 어떤 이점이 있는 걸까?
-
- 보안 강화
- API Key / Secret Hiding : 외부 PG사 API키, AI API 키 등 브라우저에 노출되면 안되는 자격 증명을 Next.js 서버 내에만 안전하게 보관할 수 있다.
- 민감 정보 차단 : 메인 백엔드가 주민번호, 전화번호 등이 포함된 DTO를 넘겨주더라도, Next.js 서버 단에서 필터링하여 브라우저 Network 탭에는 순수 화면용 데이터만 내려 보낸다.
- 쿠키 기반 인증 전환 : JWT 토큰을 브라우저 로컬 스토리지 대신 httpOnly 쿠키로 다룰 수 있어 XSS 공격에 안전하다.
-
- 프론트엔드 최적화 (Over fetching · Under fetching 해결)
- 오버페칭 해결 : 메인 백엔드 응답에 필드가 50개 있더라도, Next.js BFF에서 화면에 필요한 3개 필드만 추출하여 전달하므로 네트워크 대역폭이 획기적으로 줄어든다.
- 언더페칭 해결(API 오케스트레이션) : 화면 하나를 띄우기 위해 API 3개(유저 정보, 장바구니, 추천 상품)를 각각 불러와야 할 때, Next.js 서버에서 3개 API를 병렬로 호출하여 하나로 묶은 뒤 브라우저엔 한 번에 전달할 수 있다.
-
- 백엔드와 프론트엔드의 의존성(Coupling) 분리
- 메인 백엔드의 데이터베이스나 API 엔드포인트 구조가 크게 변경되어도, Next.js BFF의 가공 로직만 수정하면 브라우저 컴포넌트 코드는 단 한 줄도 바꿀 필요가 없습니다.
- 어떻게 보면, 프론트엔드 DTO의 기능도 대신한다. 서버 런타임 시점이라는 것과 프론트엔드 DTO는 UI 컴포넌트 보호의 설계 패턴이라는 개념이라 같은 개념은 아니지만, 일종의 상호 보완적 관계에 가깝다.
- #TIL
- #Next.js