WEB

[Python Backend] RestAPI 기반의 Flask vs FastAPI (feat. gRPC)

땽뚕 2025. 5. 25. 09:07
728x90

 

[Python Backend] RestAPI 기반의 Flask vs FastAPI (feat. gRPC)

 

 

보통 Python Backend로는 Flask vs FastAPI vs Django를 많이 비교선상에 두곤 한다. 

나도 4년전 Flask 깔짝 ... 한 적 있지만 이게 지금 이렇게 쓰일 줄 몰랐다.

그때도 Flask랑 Django 중에 뭐 공부할까 하다가 비교적 간단한 Flask를 공부했던 기억이 있다. 

LLM 서비스 특성상 빠르게 통신되어야 하고, Flask보다는 FastAPI가 두 배는 더 빠르기 때문에 (Because of 비동기 지원!!!)  FastAPI 공부 겸 ... 개념 닦기 

* 이전 포스트에서 이어집니다 (https://asidefine.tistory.com/329)

* 이후 포스트로 이어집니다 (https://asidefine.tistory.com/332)

 

항목  Flask  FastAPI  Django + DRF
프레임워크 타입 마이크로 프레임워크 비동기 지원 마이크로 프레임워크 풀스택 프레임워크 + REST 확장
비동기 지원 ❌ 기본 미지원 (추가 패키지 필요) ✅ async/await 완전 지원 🔄 제한적 (DRF + ASGI 설정 시 가능)
성능 (속도) 느림 매우 빠름 보통
설정 복잡도 매우 간단 간단 복잡함
개발 난이도 쉬움 쉬움 + 타입힌트 필요 상대적으로 어려움
자동 문서화 ❌ 수동 설정 필요 (Swagger 따로 붙여야 함) ✅ 자동 생성 (Swagger, ReDoc) ✅ 자동 생성 (DRF + CoreAPI/OpenAPI)
ORM 연동 없음 (SQLAlchemy 등 수동 설정) 없음 (Tortoise 등 외부 사용) ✅ Django ORM 완벽 통합
대규모 프로젝트 적합성 낮음 중간 ✅ 매우 높음
대표 사용처 간단한 API, 프로토타입 빠르고 효율적인 서비스 API 복잡한 웹/앱 백엔드, MSA, 기업 시스템

 

 


API 통신 방식 정리

✅ API는 목적에 따라 다양한 방식으로 구현됨

  • RESTful 방식
    • 최근 가장 많이 사용되는 방식
    • HTTP/1.1 기반 통신을 사용함
    • JSON, XML 등 형식으로 데이터를 주고받음
  • RPC 방식
    • 원격 프로시저 호출(Remote Procedure Call) 방식
    • 클라이언트가 서버의 함수를 직접 호출하듯 통신함
    • gRPC의 등장 이후 많이 쓰이는 추세임
  • Python에서는 RESTful(FastAPI, Flask)과 RPC(gRPC) 방식 모두 구현 가능함

📌 RESTful 방식

🔹 Flask

  • 가볍고 간단한 REST API 라이브러리임
  • 소규모 또는 중규모 프로젝트에 적합함
  • 표준화가 잘 되어 있지 않음
  • HTTP/1.1은 커넥션당 하나의 처리만 가능하므로, 동시 요청 처리 시 병목이 발생함
  • 프로토타입이나 기능 테스트용으로 적합함

📦 예시 코드 (Flask)

from flask import Flask, request, jsonify
from flask_swagger_ui import get_swaggerui_blueprint

app = Flask(__name__)

SWAGGER_URL = '/swagger'
API_URL = '/static/swagger.json'
swaggerui_blueprint = get_swaggerui_blueprint(
    SWAGGER_URL,
    API_URL,
    config={'app_name': "My Flask App"}
)
app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL)

@app.route('/')
def hello():
    return 'Hello, World!'

@app.route('/user/<username>')
def show_user_profile(username):
    return f'User {username}'

@app.route('/post', methods=['POST'])
def create_post():
    data = request.get_json()
    return jsonify(data), 201

if __name__ == '__main__':
    app.run(debug=True)
 

🔹 FastAPI

  • Flask보다 더 빠르고 효율적인 Framework임
  • asyncio type hint를 기반으로 버그를 줄이고 개발 생산성을 높임
  • Swagger UI와 자동 문서화가 기본 제공됨
  • HTTP/1.1의 구조적 한계를 공유함

📦 예시 코드 (FastAPI)

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(title="My FastAPI App", docs_url="/docs", redoc_url="/redoc")

class Item(BaseModel):
    name: str
    price: float

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

@app.post("/items/")
def create_item(item: Item):
    return item.dict()

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

📌 RPC 방식 (gRPC)

  • HTTP/2.0 기반으로 동작하며, 양방향 스트리밍 지원함
  • **지연(latency)**과 리소스 효율성 측면에서 HTTP/1.1보다 뛰어남
  • 하나의 커넥션에서 여러 요청/응답을 처리할 수 있음
  • 데이터는 Protocol Buffers (protobuf) 를 통해 바이너리로 직렬화되어 매우 빠름
  • MSA(Microservice Architecture) 환경에서 적극적으로 사용됨

1️⃣ .proto 파일 정의

syntax = "proto3";

package greet;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

2️⃣ gRPC 서버 구현

import grpc
from concurrent import futures
import time

from protos.greeter_pb2 import HelloReply
from protos.greeter_pb2_grpc import GreeterServicer, add_GreeterServicer_to_server

class MyGreeterServicer(GreeterServicer):
    def SayHello(self, request, context):
        return HelloReply(message=f'Hello, {request.name}!')

def run_server(host, port):
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    add_GreeterServicer_to_server(MyGreeterServicer(), server)
    server.add_insecure_port(f'{host}:{port}')
    server.start()
    print(f"Server started at {host}:{port}...")
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)

if __name__ == '__main__':
    run_server('0.0.0.0', 50051)

3️⃣ gRPC 클라이언트 구현

import grpc
from protos.greeter_pb2 import HelloRequest
from protos.greeter_pb2_grpc import GreeterStub

def run_client(host, port):
    channel = grpc.insecure_channel(f'{host}:{port}')
    stub = GreeterStub(channel)
    response = stub.SayHello(HelloRequest(name='John Doe'))
    print(response.message)

if __name__ == '__main__':
    run_client('localhost', 50051)​

4️⃣ gRPC + Swagger 연동 예시

def run_server(host, port):
    server = SwaggerDecoratedServer(
        grpc.server(futures.ThreadPoolExecutor(max_workers=10)),
        swagger_host=host,
        swagger_port=port+1,
    )
    add_GreeterServicer_to_server(MyGreeterServicer(), server)
    server.add_insecure_port(f'{host}:{port}')
    server.start()
    print(f"gRPC Server started at {host}:{port}...")
    print(f"Swagger docs: http://{host}:{port+1}/docs")
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)

🔍 비교 정리

항목FlaskFastAPIgRPC

 

통신방식 RESTful RESTful RPC
네트워크 HTTP/1.1 HTTP/1.1 HTTP/2.0
데이터 형식 JSON, XML JSON, XML Protocol Buffers (바이너리)
속도 느림 빠름 매우 빠름
주요 사용처 프로토타입, 테스트 웹/앱 서비스 MSA 아키텍처, 서비스 간 통신
 

gRPC 기반으로 해서 빨랐던 게 있었는데 ? -> Trition Inference Server

 

이전에 Trtion Inference Server 역시 RestAPI 그리고 gRPC 모두 지원한다는 부분이 떠올랐다  (https://asidefine.tistory.com/319)

이렇게 또 한 번 복습 

 

 

Reference. 

https://won-developer-log.tistory.com/entry/Python-Flask-vs-FastAPI-vs-gRPC-%EB%B9%84%EA%B5%90%EC%99%80-%EC%98%88%EC%A0%9C

 

728x90