안녕하세요.
이번 시간에는 FastAPI를 사용하면서 자주 활용되는 미들웨어에 대해 쉽게 설명해보고,
예제 코드와 함께 선언 방법을 간단히 정리해 보겠습니다.
미들웨어란?
middleware는 API 서버에 들어오는 모든 요청과 나가는 응답 사이에서
공통 작업을 처리할 수 있도록 도와주는 작은 기능 모듈입니다.
즉, 요청이 실제로 처리되기 전에 전처리를 하거나 또는
클라이언트에게 응답을 보내기 전에 후처리를하는 역할을 합니다.
대표적인 사용 예시는 다음과 같습니다.
- 요청이 들어올 때 / API 로직 처리 이후 로그를 남기는 경우
- API 함수의 소요 시간을 기록하는 경우
- 유저별 Rate Limit를 설정하려는 경우
데코레이터 방식의 미들웨어
가장 간단한 방법으로, 데코레이터를 사용해서 미들웨어 함수를 작성할 수 있습니다.
데코레이터는 함수 상단에 @app.middleware("http")의 형태로 추가해주시면 됩니다.
다음의 예제는 요청 소요 시간을 측정해서 응답 헤더에 추가하는 미들웨어입니다.
from fastapi import FastAPI, Request
import time
app = FastAPI()
@app.middleware("http") # 데코레이터로 미들웨어 선언
async def add_process_time_header(request: Request, call_next):
# 요청이 들어오기 전: 시작 시간 기록
start_time = time.time()
# call_next를 호출하면 실제 API 함수를 실행
response = await call_next(request)
# API 함수 호출이 종료되고 이후의 로직이 실행
process_time = time.time() - start_time
print(f"요청 처리 완료: {process_time:.2f}초 소요")
response.headers["X-Process-Time"] = f"{process_time:.2f}"
return response
# 이제 app과 연결된 모든 함수는 위에서 구현한 로직을 통과
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
함수 실행의 전/후는 call_next로 나뉘며, 비동기 처리를 위한 await 선언이 필요합니다.
BaseHTTPMiddleware 클래스 방식의 미들웨어
FastAPI의 근간을 이루고 있는 Starlette에서 선언된 BaseHTTPMiddleware를 상속받아
미들웨어를 구현하는 방식도 존재하는데, 확장성이 높아 많이 활용됩니다.
이 경우의 예시 코드 스니펫은 다음과 같습니다.
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
import time
class MyMiddleware(BaseHTTPMiddleware):
# dispatch라는 함수에 실행을 원하는 로직을 적어야 함
async def dispatch(self, request: Request, call_next):
# 요청이 들어오기 전: 시작 시간 기록
start_time = time.time()
# call_next를 호출하면 실제 API 함수를 실행
response = await call_next(request)
# API 함수 호출이 종료되고 이후의 로직이 실행
process_time = time.time() - start_time
print(f"Completed in {process_time:.2f} seconds")
response.headers["X-Process-Time"] = f"{process_time:.2f}"
return response
app = FastAPI()
app.add_middleware(MyMiddleware) # app에 해당 미들웨어를 직접 추가하여 선언
# 이제 app과 연결된 모든 함수는 위에서 구현한 로직을 통과
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
이 방식으로 middleware를 선언하는 경우에는 dispatch 함수 내에
원하는 로직을 적어야 한다는 특징이 있습니다.
함수 실행의 전/후가 call_next로 나뉘며, 비동기 처리를 위한 await 선언이 필요한 점은
데코레이터 방식과 동일합니다.
미들웨어 함수가 실행되는 과정에서 Request 객체를 활용하면 요청 본문 정보 등을 통하여
다양한 처리를 진행할 수 있게 됩니다.
이 글이 FastAPI를 활용한 서버 구현을 진행하는 과정에 도움이 되셨기를 기원합니다.
잘 봐주셔서 감사합니다.
'Python > Backend' 카테고리의 다른 글
FastAPI에서 pdf 파일 뷰어를 띄우는 방법 (0) | 2025.03.18 |
---|---|
FastAPI에서 Form 데이터에 대한 무결성 검증 방법 (0) | 2025.03.07 |
FastAPI 동기/비동기 설정 시 주의 사항 (0) | 2025.02.17 |