-
[Python Backend] RestAPI 기반의 Flask vs FastAPI (feat. gRPC)WEB 2025. 5. 25. 09:07728x90
[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.
728x90'WEB' 카테고리의 다른 글
[Python Backend] asyncio API 정리 (0) 2025.05.25 [Python Backend] FastAPI를 이해하기 위한 비동기 처리 개념 정리 (0) 2025.05.25 [Python Backend] Rest(HTTP)와 gRPC의 개념 (1) 2025.05.25 서버와 클라이언트 기본 구조 (0) 2021.09.03 Web에서의 페이지 전환 방법 2가지 (0) 2021.09.03 - RESTful 방식