Provisioning, BFF

Jeonghak Cho·2025년 3월 1일

Provisioning

목록 보기
6/44

BFF 프로비저닝

개요

Backend for Frontend(BFF) 는 특정 프론트엔드(웹, 모바일 앱 등)의 요구사항에 맞게 백엔드를 커스텀하여 제공하는 아키텍처 패턴이다.
일반적인 API Gateway는 모든 클라이언트(웹, 모바일, 데스크톱 등)에 대해 동일한 API를 제공하지만, BFF는 각 클라이언트별 맞춤형 API를 제공하는 것이 특징이다.

+-----------------------+      +-----------------------+
|  Web Frontend         |      |  Mobile Frontend      |
+-----------------------+      +-----------------------+
           |                            |
           v                            v
+-----------------------+      +-----------------------+
|  Web BFF API         |      |  Mobile BFF API      |
+-----------------------+      +-----------------------+
           |                            |
           v                            v
+---------------------------------------+
|  Main Backend API                     |
+---------------------------------------+

단점

아래와 같은 단점이 있으므로 유의해서 사용한다.

  • BFF 개수 증가로 인한 관리 복잡성 → 클라이언트가 많아질수록 BFF도 많아짐
  • API Gateway와 중복 가능성 → API Gateway가 일부 역할을 수행할 수도 있음
  • 추가적인 개발 비용 → 일반적인 API 서버보다 설계 및 개발 비용 증가

적용 시점

  • 웹과 모바일에서 다른 API 응답이 필요할 때
  • 클라이언트별 요청을 최적화해야 할 때 (모바일에서는 데이터 축소)
  • 각 클라이언트별 개발 팀이 다를 때 (웹 팀 / 모바일 팀 분리)
  • API 변경을 특정 클라이언트에만 반영하고 싶을 때

BFF vs API Gateway 차이점

특징BFF (Backend for Frontend)API Gateway
목적클라이언트 맞춤형 API 제공모든 API 트래픽 관리
요청 처리특정 프론트엔드 요청만 처리모든 서비스 요청을 라우팅
데이터 최적화클라이언트별 응답 최적화일반적으로 원본 데이터를 전달
보안프론트엔드 맞춤 보안 적용 가능인증/인가 등 공통 보안 처리
확장성특정 클라이언트 증가 시 BFF 추가 필요모든 클라이언트에 동일하게 적용

할일

Flask는 Python 기반의 마이크로 웹 프레임워크로, 가벼우면서도 확장성이 뛰어난 것이 특징이다. Django와 같은 풀스택 프레임워크에 비해 간결하고 유연한 개발이 가능하다.
기본적으로 가벼운 프레임워크지만, 필요한 기능을 추가하여 확장 가능하다. 대표적인 확장 기능으로는 Flask-SQLAlchemy → 데이터베이스 ORM, Flask-RESTful → REST API 개발, Flask-JWT → 인증 및 보안 등이 있다.
웹 프레임워크를 flask로 선택한 후 필요한 일을 정의한다. Flask는 빠른 프로토타이핑 및 MVP 개발에 적합하고, 자동 디버그 모드를 제공 (debug=True 설정)한다.

  • 확장에 유연한 python3 테스트 환경 구축
  • 참조 용 기본 bff 소스 작성

절차

  • 파이썬 소스 (app.py) 작성
  • app.py 로컬 테스트
  • 도커파일 생성
  • 도커 빌드
  • 도커 단위 테스트

진행

파이썬 소스 (bff.py) 작성

import requests
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/', methods=['GET'])
def web_home():
    return jsonify({
        "title": "Welcome to Web",
        "content": "This is web-specific content."
    })

@app.route('/bff')
def call_bff():
    print("CALLED backend for frontend!")
    response = requests.get("http://backend:5000/health")
    return f"BFF RESPONSE: {response.text}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=3000)

bff.py 로컬 테스트

vagrant@slave1:~$ pip install flask

vagrant@slave1:~$ python3 bff.py
 * Serving Flask app 'bff'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:3000
 * Running on http://10.0.2.15:3000
Press CTRL+C to quit
vagrant@slave1:~$ curl localhost:3000/
{"content":"This is web-specific content.","title":"Welcome to Web"}

도커파일 생성

FROM python:3.11-slim
USER root
WORKDIR /app
RUN apt-get update && \
    apt-get install -y curl vim && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN pip install flask
RUN pip install requests
COPY ./bff.py /app

EXPOSE 3000

CMD ["python3", "bff.py"]

도커 빌드

sudo docker build . -t bff:0.1 -f Dockerfile-bff
vagrant@slave1:~$ sudo docker images
REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
bff                     latest    2275199385bc   4 minutes ago   196MB

도커 단위 테스트

vagrant@slave1:~$ sudo docker run -p 3000:3000 bff
 * Serving Flask app 'bff'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:3000
 * Running on http://172.17.0.4:3000
Press CTRL+C to quit
vagrant@slave1:~$ curl localhost:3000
{"content":"This is web-specific content.","title":"Welcome to Web"}

도커 이미지 태깅

sudo docker tag bff:0.1 chojeonghak/mypython:bff-0.1
sudo docker push chojeonghak/mypython:bff-0.1

쿠버네티스 배포

bff.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bff
spec:
  selector:
    matchLabels:
      app: bff
  replicas: 1
  template:
    metadata:
      labels:
        app: bff
    spec:
      containers:
      - name: bff
        image: chojeonghak/mypython:bff-0.1
        ports:
        - containerPort: 3000
k apply -f bff.yml
vagrant@slave1:~$ k get po
NAME                             READY   STATUS        RESTARTS   AGE
bff-bb4d4d947-zq9m8              1/1     Running       0          26s

vagrant@slave1:~$ k exec -it bff-bb4d4d947-zq9m8 -- curl localhost:3000
{"content":"This is web-specific content.","title":"Welcome to Web"}

0개의 댓글