python / / 2024. 8. 16. 14:25

[fastapi] 미들웨어(Middleware) 이해하기

1. 미들웨어(Middleware)란?

미들웨어는 요청이 들어오고 응답이 나가기 전에 실행되는 함수나 클래스이다. FastAPI에서 미들웨어는 모든 HTTP 요청에 대해 공통적으로 실행되는 코드를 작성할 때 유용하다. 예를 들어, 요청의 처리 시간을 기록하거나, 모든 응답에 공통된 헤더를 추가하는 작업 등을 미들웨어에서 수행할 수 있다.

2. @app.middleware("http") 데코레이터를 사용한 미들웨어

FastAPI에서 미들웨어를 정의하는 가장 기본적인 방법은 @app.middleware("http") 데코레이터를 사용하는 것이다. 이 데코레이터는 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()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

위 코드에서는 add_process_time_header라는 미들웨어가 정의되어 있다. 이 미들웨어는 요청이 들어오면 먼저 처리 시간을 측정하고, 요청을 다음 처리 단계로 넘긴 후, 응답에 처리 시간을 기록한 X-Process-Time 헤더를 추가한다.

처리된 응답결과는 다음과 같다.

HTTP/1.1 200 OK
date: Fri, 16 Aug 2024 05:17:42 GMT
server: uvicorn
content-length: 4
content-type: application/json
x-process-time: 0.000293731689453125

2.1. requestcall_next

  • request: 클라이언트로부터 들어온 HTTP 요청 객체이다. 이 객체를 통해 요청 메서드, 헤더, URL 등 다양한 정보에 접근할 수 있다.
  • call_next: 다음 미들웨어나 경로 함수로 요청을 넘기는 함수이다. 이 함수가 호출되면 FastAPI는 요청을 처리하고 응답을 생성한다.

3. 미들웨어 사용 사례

미들웨어는 다양한 상황에서 활용될 수 있다. 다음은 몇 가지 일반적인 사용 사례이다.

3.1. 요청 로깅

모든 요청의 정보를 로깅하려는 경우 미들웨어를 사용하면 쉽게 구현할 수 있습니다.

from fastapi import FastAPI, Request
import logging

app = FastAPI()

logging.basicConfig(level=logging.INFO)

@app.middleware("http")
async def log_requests(request: Request, call_next):
    logging.info(f"Request URL: {request.url.path}")
    response = await call_next(request)
    logging.info(f"Response status code: {response.status_code}")
    return response

이 코드에서는 log_requests 미들웨어가 모든 요청 URL과 응답 상태 코드를 로깅한다. 이렇게 하면 애플리케이션의 동작을 쉽게 모니터링할 수 있다.

3.2. CORS 헤더 추가

모든 응답에 CORS 헤더를 추가하여 클라이언트가 다른 도메인에서 API에 접근할 수 있도록 설정할 수 있다.

from fastapi import FastAPI

app = FastAPI()

@app.middleware("http")
async def add_cors_headers(request, call_next):
    response = await call_next(request)
    response.headers["Access-Control-Allow-Origin"] = "*"
    return response

이 예제에서는 모든 응답에 Access-Control-Allow-Origin: * 헤더를 추가하여, 어떤 도메인에서도 API에 접근할 수 있도록 설정하고 있다.

4. 클래스 기반 미들웨어

미들웨어는 함수 외에도 클래스로 정의할 수 있다. 클래스 기반 미들웨어는 상태를 유지하거나 초기화 작업이 필요한 경우 유용하다.

from starlette.middleware.base import BaseHTTPMiddleware
from fastapi import FastAPI

app = FastAPI()

class CustomMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers["X-Custom-Header"] = "CustomValue"
        return response

app.add_middleware(CustomMiddleware)

위 코드에서는 CustomMiddleware라는 클래스를 사용해 미들웨어를 정의하고, app.add_middleware를 통해 FastAPI 애플리케이션에 추가하고 있다. 이 미들웨어는 모든 응답에 X-Custom-Header 헤더를 추가한다.

5. 미들웨어의 순서

여러 개의 미들웨어를 사용하는 경우, 미들웨어의 순서가 중요하다. FastAPI는 미들웨어를 정의된 순서대로 실행한다. 예를 들어, 인증 미들웨어가 로그 미들웨어보다 먼저 실행되어야 하는 경우, 해당 순서로 미들웨어를 정의해야 한다.

app.add_middleware(AuthenticationMiddleware)
app.add_middleware(LoggingMiddleware)

이 순서로 정의하면, 인증 미들웨어가 먼저 실행된 후 로그 미들웨어가 실행된다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유