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 (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 설정)한다.
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)
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"}