이력서를 보다가 BFF라는 용어를 보게 되었다.
워딩만 봤을때는 프론트를 위한 백엔드라는 용어 같은데, 어떤 의미인지 구체적으로 찾아보기로 하자!
BFF를 이야기 하기 전에 MSA를 알아야한다.
MSA(Micro Service Architecture)는, 독립적인 배포가 가능한 서비스들로 구성된 아키텍처라는 의미를 갖는다.
기존에는 모든 서비스가 한 곳에 모인 monolitic한 구조로 개발을 진행하는 경우가 많았지만, 서비스의 구조가 커지면서 모놀리틱한 구조로는 해결이 어려운 문제들에 직면하게 되고, 이를 해결하기 위해 MSA로 서비스를 전환하거나 시도하는 곳이 늘어나고 있다.
MSA-서비스를 도메인별로 분리
서비스는 작은 서비스의 집합으로 구성되며, 각 서비스는 독립적이고 단일 비즈니스 기능에 대한 책임만을 가진다.
frontend 관점에서?
MSA 구조에서는 각 서비스가 기능별로 흩어져 있으므로 화면을 완성하기 위해 호출해야 하는 서비스도 늘어나게 된다. 따라서 화면을 그리기 위해서는 다수의 서비스에 연동해야하며, 여러 서비스에 분산되어있는 데이터를 가져와서 적절히 합쳐야하는 경우도 발생하게 된다.
그래서 BFF!
이를 돕기 위해 BFF가 등장하게 되었다. 말 그대로 클라이언트가 백엔드 API를 직접 호출할 때 발생하는 여러가지 문제를 해결하기 위해, 프론트엔드를 위한 백엔드 서버를 의미한다. BFF는 클라이언트와 백엔드 사이에서 데이터 가공 및 전달을 담당하며, 이를 통해 프론트엔드가 효율적으로 동작할 수 있도록 도와준다. 프론트엔드 요구사항에 맞게 구현하기 위한 도움을 주는 보조 서버 정도로 이해할 수 있다.
MSA 라면 고객, 주문, 물건, 장바구니 등 커머스 도메인 별로 나뉘어 서비스가 구현되어 있다. 각 서비스는 프론트엔드에서 사용하는 API를 제공한다. MSA 환경에서 여러 API로부터 받은 데이터를 조합 및 가공하기 위해 활용된다. 과거 모놀리식 아키텍처에서는 단일 백엔드서버가 모든 로직을 처리했고, 프론트는 서버로부터 받은 데이터를 단순히 렌더링하는 역할을 했다. 하지만 MSA로 전환하면서 프론트엔드는 여러 서비스의 API를 호출해야했고, 이 데이터를 조합하거나 가공해야 하는 부담이 생겼다. API 호출 수가 늘어나고, 클라이언트 코드의 복잡도가 증가하는 문제가 발생했다. BFF는 이러한 문제를 해결하기 위해 중간 계층 역할을 하며 여러 API에서 데이터를 받아 프론트엔드가 필요로 하는 형태로 가공하여 전달한다. 이를 통해 클라이언트 단의 불필요한 API 호출을 줄이고, 프론트엔드의 복잡도를 낮추면서도 최적화된 데이터 제공이 가능하게 된다.
BFF는 다양한 플랫폼 환경에 맞는 데이터로 가공하기 위해 활용된다. 웹, 모바일, 스마트TV 등 여러 종류의 프론트엔드 플랫폼이 등장하면서, 각 플랫폼에 적합한 데이터 형식과 응답 구조가 필요하게 되었다. 예를 들어, 웹 애플리케이션은 상대적으로 복잡한 데이터 구조를 받아도 큰 문제가 없지만, 모바일 애플리케이션의 경우 네트워크 비용을 줄이기 위해 최소한의 데이터만 요청하는 것이 유리하다. BFF를 활용하면 플랫폼의 특성에 맞춰 데이터를 변환하거나 선택적으로 제공할 수 있으며, 이를 통해 성능 최적화도 이룰 수 있다.
API 키 및 인증 정보 관리, CORS 문제 해결 등 클라이언트 단에서 발생할 수 있는 다양한 이슈를 효과적으로 해결할 수 있다. 또한, 백엔드 시스템 변경시 프론트엔드 코드의 수정 범위를 최소화 하는 역할도 수행할 수 있어 유지보수성을 높이는데 도움이 되기도 한다. (하단 실제 활용 예시에서 계속!)
얼핏보면 기능별로 나뉘어져 서비스가 잘 분리되어 문제가 될만한 점이 보이지 않을 수 있으나, 실제로 개발을 진행하다 보면 여러 고민들에 봉착하게 된다.
💡 하나의 view를 완성하기 위해 여러 도메인의 API응답값을 조작해야 하는 경우
이를테면, 고객의 등급을 조회하는 페이지에서 등급 업그레이드까지 남은 주문 금액을 디스플레이 하기 위해 주문 데이터를 살펴보아야 할 수도 있다. 혹은 특정 주문 데이터의 결제 현황을 조회하기 위해 결제 서비스를 호출해야하는 경우도 있을 수 있다. 즉 원하는 응답값을 얻기 위해 여러 서비스를 호출해야 하는 상황이다.
💡 데이터를 전송하는 과정에서 불필요한 데이터를 숨겨야 하는 경우
결제 서비스를 이용하기 위한 유저별 secret key와 같은 비공개성 정보들이 존재할 수 있다. 브라우저를 통한 네트워크 통신은 항상 위험에 노출되어있기 때문에, 해당 정보를 보관하고 결제 서비스 요청시 심어주기 위한 인터페이스 서버가 필요한 상황이다.
💡 프론트엔드에서 많은 양의 연산을 요구하는 작업을 진행해야하는 경우
주문 정보 엑셀 다운로드와 같이 브라우저의 자원을 많이 소모하거나, 고객 정보 일괄 수정 등 다수의 네트워크 통신을 유발하는 작업을 진해해야하는 경우가 있을 수 있다. 브라우저에서 복잡한 연산을 수행하는 경우 렌더링 성능에 악영향을 끼칠 수 있기 때문에 역시 개선이 필요한 상황이다.
그래서 BFF
이런 경우 BFF가 좋은 해결책이 될 수 있다. BFF를 두는 목적은 프론트엔드의 로직에 중간 레이어를 두어 BFF에 위임하는 것이다. 이로써 프론트엔드는 구체적인 구현 내용을 감추고, 추상화된 API를 사용할 수 있게 된다. 결과적으로 프론트엔드에는 더 적은 로직이 남게 된다.
🔥BFF 구조 활용 사례
1. Netflix
넷플릭스는 다양한 디바이스에서 실행되며, 각 플랫폼마다 요구하는 데이터 형식이 다름
활용
- 웹, 모바일, TV 등 각 디바이스에 맞춘 BFF 서버를 운영하여 최적화된 API 응답을 제공
- 예를들어, 모바일에서는 저화질 썸네일과 최소한의 데이터만 제공하고, 웹에서는 더 많은 상세정보를 포함하도록 구성
2. Spotify
음악 스트리밍 서비스로서, 데스크톱 앱, 웹앱, 모바일 앱 등에서 동일한 데이터를 다르게 가공해야 함.
활용
- 각 플랫폼에 맞는 API 응답을 조정하여 최적의 사용자 경험 제공
- 모바일에서는 네트워크 트래픽을 줄이기 위해 곡 리스트를 단순화하고, 웹에서는 상세한 곡 정보와 추천 목록을 함께 제공
3. Airbnb
호스트와 게스트가 사용하는 앱의 인터페이스가 다름.
활용
- 게스트용 BFF : 숙소 검색, 예약, 리뷰 등의 기능을 최적화
- 호스트용 BFF : 예약관리, 수익 통계, 메세지 관리 등과 관련된 API를 최적화
4. 전자상거래플랫폼
고객과 판매자가 사용하는 인터페이스가 다르고, 모바일과 웹에서 필요한 데이터가 다름
활용
- 고객용 : 상품 목록, 추천, 장바구니 기능을 최적화
- 판매자용 : 주문관리, 재고확인, 매출통계를 제공하는 API 제공
💡 이전에 판매플랫폼을 토이프로젝트로 구현한 경험이 있었는데, 이 과정에서 같은 API를 가지고 동일하게 호출하여 프론트 단에서 이를 가공하여 데이터를 보여주는 구현을 한 경험이 있다. 그런데 게스트용/고객용 처럼 인터페이스별로 API 구조를 나누게 되면
필요한 데이터만 가지고 효과적으로 화면을 구현할 수 있을 것 같다. 이전엔 모두 다 받아서 필요한 정보를 표현하는 방식이었다면
결과적으로 플랫폼을 사용하는 클라이언트단에 효율적인 방법으로 화면을 제공할 수 있도록 생각하게 되는 구조이다. 현업에서 직접 적용하긴 어려움이 있을 수 있지만, 다음번에 토이프로젝트를 하게 된다면 이러한 방식도 적용해보면 좋을 것 같다.
그러다 궁금한 내용..
그러면 서버에서 클라이언트단에 목적에 맞게 API를 가공하여 제공해주는 방식인데, 이 부분이 서버 개발자에게 부담이 될 수 있지않을까?
애초 BFF는 클라이언트 목적에 맞게 API를 분리하고 관리하는 것인데, 이는 백엔드 개발자가 커버해야할 범위가 넓어지는 부담이 될 수 있을 것 같다.
🚀 BFF 구조의 핵심 역할
백엔드 API는 표준화된 데이터만 제공
일반적인 REST API나 GraphQL을 통해 데이터의 원천(Source of Truth)을 유지
예: 주문 정보를 제공하는 /orders API → 주문 상세 정보, 상태값, 결제 정보 등 모든 데이터를 포함
BFF에서 클라이언트 맞춤형 데이터 제공
각 클라이언트에 필요한 데이터만 필터링하거나 구조를 변경
모바일 BFF → 데이터 양을 줄이고, 이미지 URL을 최적화
웹 BFF → 더 많은 정보를 포함하여 상세 화면 지원
클라이언트가 API를 조합할 필요 없음
프론트엔드는 여러 개의 API를 호출해 데이터를 조합하는 대신, BFF에서 가공된 최적의 응답을 바로 받아 사용
기존 방식 → /users, /orders, /payments API를 따로 호출해서 데이터를 조합
BFF 방식 → /dashboard 하나만 호출하면 필요한 정보가 한 번에 내려옴
📌 BFF를 백엔드 개발자가 부담스럽게 느낄 수 있는 이유
백엔드 입장에서 보면, BFF는 기존 API 외에 추가로 관리해야 할 계층이 생기는 것이므로 부담스럽게 느껴질 수 있어요.
- 기존에는 하나의 API만 만들면 되었는데, 웹용 BFF, 모바일용 BFF 등 여러 개를 관리해야 하는 부담이 생김
- 클라이언트 요구사항이 바뀔 때마다 BFF 로직도 수정해야 하는 추가적인 유지보수 부담 발생
- 캐싱, 로깅, 인증 같은 공통 로직을 어디서 처리할지 고민 필요
🔥 그렇다면 BFF를 도입하려면 어떻게 설득할까?
✅ 백엔드 API는 비즈니스 로직에 집중, BFF는 클라이언트 맞춤형 응답 제공
- 백엔드에서는 데이터를 표준 형태로만 제공하고, 클라이언트별 응답 형식 변경은 BFF에서 담당
- 백엔드 개발자의 부담을 줄이기 위해 BFF는 가능한 가벼운 변환 역할만 수행
✅ 클라이언트별 최적화된 API가 필요하다는 점 강조
- 모바일에서는 데이터 최적화가 필수적 (불필요한 필드 제거, 응답 크기 줄이기)
- 웹과 모바일의 UI/UX가 다르면 필요한 데이터 구조도 달라짐
- 하나의 공통 API를 그대로 사용하면 프론트엔드에서 불필요한 데이터 처리가 필요함
✅ BFF를 백엔드 팀에서 담당할지, 프론트엔드 팀에서 관리할지 논의
- 백엔드 팀에서 관리 → 기존 API 설계와 일관성을 유지하면서 관리 가능
- 프론트엔드 팀에서 관리 → Node.js/Express, Next.js API Routes 등을 활용해 필요한 데이터를 직접 가공 가능
🎯 결론
BFF 구조에서는 백엔드 개발자가 클라이언트별 API를 따로 만들어야 하는 부담이 생길 수 있다는 점이 맞아요.
하지만 **"프론트엔드가 직접 API를 조합하고 가공하는 구조를 피하기 위해서라도 BFF가 필요하다"**는 점을 강조하면 더 효과적으로 설득할 수 있을 거예요. 😊
라는 지선생님의 조언,..
그러면 최초 프로젝트의 목적성을 명확히 하고 시작하면 서로에게 부담이 덜하겠다!
🚀 목표 정할 때 고려할 질문들
- ✅ 클라이언트별 맞춤 API가 정말 필요한가?
→ Web, iOS, Android의 요구사항이 크게 다르다면 BFF 필요 - ✅ BFF가 없으면 프론트엔드에서 데이터 가공이 너무 복잡한가?
→ 프론트에서 여러 개의 API를 호출하고 조합해야 한다면 BFF가 효율적 - ✅ BFF가 추가되었을 때 백엔드 유지보수 부담은 감당 가능한가?
→ API 변경이 잦은 프로젝트라면 백엔드 부담이 커질 수도 있음 - ✅ BFF는 누가 관리할 것인가?
→ 백엔드 팀? 프론트엔드 팀? 아니면 협업?
그리고 이 프로젝트에서 정말 BFF가 필요한가? 에 대해 중심적으로 논의하는 부분이 우선적으로 필요할 것 같다.
'프론트엔드 개발자로 일하기' 카테고리의 다른 글
tui-editor 에서 customHTMLSanitizer 커스텀해서 사용하기 (0) | 2024.09.10 |
---|---|
thymeleaf에서 fragment로 vue 컴포넌트 만들기 (0) | 2024.09.03 |
이슈 트래킹 - lazy loading (2) | 2024.09.01 |
후루룹 말아먹고 써보는 github 이야기.. (0) | 2024.09.01 |
보일러플레이트(boiler Plate) 코드 (0) | 2024.09.01 |