Что такое Middleware в веб-фреймворках и какие задачи оно решает

Ответ

Middleware (промежуточное ПО) — это компонент, который встраивается в конвейер обработки HTTP-запроса и ответа в веб-приложении. Он обрабатывает запрос до того, как он достигнет основного обработчика (view/controller), и/или обрабатывает ответ перед его отправкой клиенту.

Middleware можно представить как слои луковицы: запрос последовательно проходит через каждый слой на пути к ядру приложения, а ответ возвращается через них в обратном порядке.

Основные задачи, решаемые с помощью Middleware:

  • Аутентификация и авторизация: Проверка учетных данных пользователя и его прав доступа.
  • Логирование: Запись информации о каждом входящем запросе и исходящем ответе.
  • Обработка ошибок: Централизованный перехват исключений и формирование стандартизированных ответов об ошибках.
  • CORS: Добавление необходимых заголовков для кросс-доменных запросов.
  • Сжатие: Сжатие тела ответа (например, с помощью Gzip) для уменьшения трафика.
  • Кеширование: Добавление заголовков для управления кешированием на стороне клиента или сервера.

Пример Middleware в FastAPI:

Этот Middleware измеряет время обработки запроса и добавляет его в заголовки ответа.

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()

    # Передача запроса следующему Middleware или обработчику
    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!"}

В Django Middleware конфигурируются в settings.py в виде списка классов, а во Flask могут быть реализованы через декораторы (@app.before_request) или как WSGI-обертки.

Ответ 18+ 🔞

А, слушай, вот эта ваша middleware, промежуточное ПО, это ж такая штука, блядь, как лук, понимаешь? Запрос идёт, а его по слоям, сука, чистят, пока до сердцевины не доберётся. И обратно так же, блядь, через все эти прослойки выходит.

Ну, то есть, если по-простому: это такие охранники, блядь, на пути у твоего HTTP-запроса. Один проверяет пропуск — это аутентификация. Другой смотрит, можно ли тебе в этот кабинет — авторизация. Третий, блядь, всё в журнал записывает, кто приходил и когда — логирование. А четвёртый, если ты накосячил и упал, подхватывает и красивую ошибку тебе показывает, а не просто пиздец на экране. Ёпта, удобно же!

Вот смотри, как в FastAPI это выглядит, простой пример, который засекает, сколько времени запрос обрабатывался:

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!"}

Видишь? Всё просто, как три копейки. До эндпоинта что-то делаем, потом вызываем call_next, ждём, пока там внутри вся магия произойдёт, и потом, когда ответ уже готов, ещё что-то своё к нему прикручиваем. Красота, блядь!

В Django это, конечно, через settings.py настраивается, список классов, а во Flask можно через декораторы @app.before_request или обёртки WSGI. Но суть-то одна, блядь — прослойка, которая всё видит и со всем может похулиганить, пока запрос туда-сюда болтается. Ёперный театр, а не архитектура!