Python/fastapi

Middleware

metamong-data 2025. 1. 14. 14:28
728x90
반응형

개요

FastAPI에서 미들웨어(Middleware)는 요청(Request)과 응답(Response) 사이에 실행되는 함수 또는 클래스입니다. 이를 통해 요청 처리 전에 또는 응답 반환 전에 특정 작업을 수행할 수 있습니다. 미들웨어는 로깅, 인증, 요청 수정, 응답 헤더 추가 등 다양한 용도로 사용됩니다.

이 문서에서는 FastAPI의 미들웨어에 대해 자세히 설명하고, 사용 예제를 제공합니다.


미들웨어 동작 원리

  1. 요청 흐름: 클라이언트가 서버로 요청을 보낼 때 미들웨어가 요청을 가로채고, 필요한 처리를 수행한 후 애플리케이션으로 요청을 전달합니다.

  2. 응답 흐름: 애플리케이션에서 응답이 생성된 후 미들웨어가 응답을 가로채고, 필요한 처리를 수행한 후 클라이언트로 반환합니다.


미들웨어 추가하기

FastAPI에서 미들웨어를 추가하려면 add_middleware 메서드를 사용하거나, @app.middleware 데코레이터를 활용할 수 있습니다.

1. 미들웨어 클래스 사용하기

기본 구조

FastAPI에서 제공하는 BaseHTTPMiddleware 클래스를 상속하여 미들웨어를 정의할 수 있습니다.

예제: 요청 로깅 미들웨어

from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
import logging

app = FastAPI()

class LoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 요청 정보 로깅
        logging.info(f"Request: {request.method} {request.url}")
        response = await call_next(request)
        # 응답 정보 로깅
        logging.info(f"Response status: {response.status_code}")
        return response

# 미들웨어 추가
app.add_middleware(LoggingMiddleware)

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

결과

  • 클라이언트 요청과 응답 상태 코드가 로깅됩니다.

  • 로깅 내용은 INFO 레벨로 출력됩니다.


2. 데코레이터를 사용한 미들웨어 추가

@app.middleware("http") 데코레이터를 사용하여 간단한 미들웨어를 정의할 수 있습니다.

예제: 응답 헤더 추가

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.middleware("http")
async def add_custom_header(request: Request, call_next):
    response = await call_next(request)
    response.headers["X-Custom-Header"] = "CustomValue"
    return response

@app.get("/")
async def read_root():
    return {"message": "Hello, Middleware!"}

결과

  • 모든 응답에 X-Custom-Header: CustomValue가 추가됩니다.

실전 예제

1. 요청 시간 측정 미들웨어

설명

  • 요청 처리 시간을 측정하고, 이를 응답 헤더에 포함시킵니다.

코드

import time
from fastapi import FastAPI, Request

app = FastAPI()

@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

@app.get("/")
async def read_root():
    return {"message": "Check the X-Process-Time header!"}

결과

  • 모든 응답에 처리 시간이 X-Process-Time 헤더로 포함됩니다.

2. 인증 미들웨어

설명

  • 요청 헤더에 Authorization이 없는 경우 요청을 거부합니다.

코드

from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.middleware("http")
async def check_auth_header(request: Request, call_next):
    if "Authorization" not in request.headers:
        raise HTTPException(status_code=401, detail="Authorization header missing")
    response = await call_next(request)
    return response

@app.get("/protected")
async def protected_endpoint():
    return {"message": "You have access!"}

결과

  • Authorization 헤더가 없는 요청은 401 Unauthorized 응답을 받습니다.

여러 미들웨어 적용 순서

  1. FastAPI는 미들웨어를 등록된 순서대로 실행합니다.

  2. 요청은 위에서 아래로, 응답은 아래에서 위로 처리됩니다.

예제

@app.middleware("http")
async def middleware_one(request: Request, call_next):
    print("Middleware 1: Before Request")
    response = await call_next(request)
    print("Middleware 1: After Response")
    return response

@app.middleware("http")
async def middleware_two(request: Request, call_next):
    print("Middleware 2: Before Request")
    response = await call_next(request)
    print("Middleware 2: After Response")
    return response

@app.get("/")
async def read_root():
    return {"message": "Check middleware order!"}

출력

Middleware 1: Before Request
Middleware 2: Before Request
Middleware 2: After Response
Middleware 1: After Response

결론

FastAPI의 미들웨어는 요청과 응답을 처리하는 강력한 도구입니다. 적절한 미들웨어를 사용하면 애플리케이션의 유지보수성과 확장성을 높일 수 있습니다. 위에서 소개된 예제를 활용해 다양한 요구사항에 맞는 미들웨어를 설계해보세요.

728x90

'Python > fastapi' 카테고리의 다른 글

SQLAlchemy 사용법  (0) 2025.01.08
Alembic 사용법  (1) 2025.01.08