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

Ответ

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.

Ответ 18+ 🔞

А, слушай, middleware, ну это ж такая штука, которая как будто стоит на проходной, блядь. Все запросы через неё проходят, туда и обратно. Ну, типа, охранник на входе в клуб, который проверяет, есть ли у тебя браслет, а на выходе ещё и по спине похлопает, мол, заходи ещё, пидарас.

Вот, например, если тебе надо засечь, сколько времени запрос пиздует по твоему приложению, или логировать, кто и куда ломится, или проверять, не мудак ли ты, который без токена пришёл — это всё middleware, ёпта.

Смотри, как это в разных фреймворках выглядит, а то они, блядь, как два разных начальника цеха — у каждого свои порядки.

1. FastAPI: Всё через жопу, но асинхронно и быстро

Тут middleware — это просто асинхронная функция, сука. Сидит себе, ждёт, когда ей 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"}

Видишь? Вешаешь на приложение декоратор @app.middleware("http") — и всё, твоя функция теперь как швейцар, который каждому входящему секундомер под жопу суёт. Красота, блядь.

2. Django: Классы, настройки, всё серьёзно, как в конторе

А вот в Django, сука, уже не шутки. Тут middleware — это целый класс, у которого должны быть методы __init__ и __call__. Будто ты не программист, а на собеседовании в корпорацию пиздишь.

Пример: middleware для логирования, чтобы знать, кто тут шастает

  1. Пишем класс в каком-нибудь 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 ты должен прописать своего «сотрудника» в трудовой книжке проекта, иначе он на работу не выйдет, пидарас.

Короче, суть одна: middleware — это такой универсальный фильтр, куда можно запихнуть любую сквозную логику, чтобы не пиздеть одно и то же в каждом обработчике. Выбирай инструмент по душе, только не перепутай, а то один тебя поймёт, а другой — в рот тебя чих-пых!