Как создать собственный middleware в FastAPI и Django?

«Как создать собственный middleware в FastAPI и Django?» — вопрос из категории Архитектура, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Middleware (промежуточное ПО) — это компонент, который обрабатывает запрос на пути к обработчику эндпоинта и ответ на обратном пути. Его используют для сквозных задач: аутентификации, логирования, сбора метрик, обработки ошибок.

Реализация зависит от веб-фреймворка.

1. FastAPI

В FastAPI middleware — это async функция, которая принимает request и функцию call_next для передачи управления дальше по цепочке.

Пример: измерение времени обработки запроса

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 root():
    return {"message": "Hello World"}

Middleware добавляется к приложению с помощью декоратора @app.middleware("http").

2. Django

В Django middleware — это класс с методами __init__ и __call__.

Пример: простой middleware для логирования

  1. Создайте файл myapp/middleware.py:

    # myapp/middleware.py
    import logging
    
    logger = logging.getLogger(__name__)
    
    class LoggingMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
            # Одноразовая настройка при запуске сервера
    
        def __call__(self, request):
            # Код, выполняемый перед обработкой запроса view
            logger.info(f"Processing request: {request.path}")
    
            response = self.get_response(request)
    
            # Код, выполняемый после обработки запроса view
            logger.info(f"Response status code: {response.status_code}")
            return response
  2. Зарегистрируйте его в settings.py:

    Добавьте путь к вашему классу в список MIDDLEWARE.

    # settings.py
    MIDDLEWARE = [
        # ... стандартные middleware Django
        'myapp.middleware.LoggingMiddleware', # Добавляем наш middleware
    ]

Ключевое отличие: FastAPI использует более легковесный, асинхронный подход на основе декораторов, в то время как Django применяет более строгую систему классов, конфигурируемую в settings.py.