Ответ
Middleware (промежуточное ПО) — это компонент, который обрабатывает HTTP-запросы и ответы до или после их обработки основным обработчиком (view-функцией) в веб-фреймворках. Он позволяет выполнять общую логику, не дублируя ее в каждом эндпоинте.
Пример использования в FastAPI:
from fastapi import FastAPI, Request, Response
import time
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
# Логика до обработки запроса (например, логирование, аутентификация)
print(f"Request received: {request.url}")
response = await call_next(request)
# Логика после обработки запроса (например, добавление заголовков, сжатие)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(round(process_time, 4))
print(f"Request processed in {process_time:.4f} seconds")
return response
@app.get("/")
async def read_root():
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
Объяснение:
- Декоратор
@app.middleware("http")регистрирует асинхронную функциюadd_process_time_headerкак middleware для HTTP-запросов. request: Request— объект входящего запроса.call_next— функция, которая передает управление следующему middleware или основному обработчику маршрута. Ее вызов возвращаетResponse.- Код до
await call_next(request)выполняется до обработки запроса. - Код после
await call_next(request)выполняется после обработки запроса, позволяя модифицировать ответ.
Преимущества использования middleware:
- Централизация логики: Аутентификация, логирование, обработка ошибок, добавление заголовков, сжатие ответов.
- Повторное использование: Избегание дублирования кода в различных эндпоинтах.
- Модульность: Легкое добавление или удаление функциональности без изменения основной бизнес-логики.
Ответ 18+ 🔞
Так, слушай, про middleware, это же просто пиздец какая удобная штука, если врубиться. Представь себе, блядь, бармена в баре, да? Не каждый же клиент сразу к стойке прёт, чтобы ему налили. Сначала швейцар дверь открывает, потом гардеробщик куртку принимает, потом охранник смотрит, не пиздит ли кто-нибудь чего. Вот эти все ребята — они и есть middleware, ёпта! Они запрос (клиента) обрабатывают, пока он до главного обработчика (бармена) не дойдёт.
А в коде это выглядит примерно так, смотри, не усни только:
from fastapi import FastAPI, Request, Response
import time
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
# Вот тут мы делаем что-то ДО того, как запрос попадёт куда надо
print(f"Пришёл запрос на: {request.url}")
response = await call_next(request) # А это — священный момент! Передаём эстафету дальше!
# А вот тут мы уже ПОСЛЕ того, как бармен (обработчик) отработал
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(round(process_time, 4))
print(f"Запрос обработан за {process_time:.4f} секунд, ядрёна вошь!")
return response
@app.get("/")
async def read_root():
return {"message": "Hello World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
Чё тут вообще происходит, по косточкам:
@app.middleware("http")— это как повесить табличку «Здесь сидит тётенька, которая всех пропускает через себя». Функция под ним становится этим самым посредником.request: Request— это сам клиент, который пришёл, со всеми своими хотелками (заголовками, куками и прочей хуйнёй).call_next— это, блядь, волшебная кнопка «ПУСК». Ты её жмёшь и говоришь: «Ну всё, иди дальше по цепочке, пусть следующий мудак разбирается».- Всё, что до
await call_next(request)— выполняется ДО основной логики. Типа «ой, кто это к нам пришёл, давайте засечём время, проверим права». - Всё, что после — это уже ПОСЛЕ. Ответ от бармена уже есть, можно к нему прилепить какую-нибудь бумажку (заголовок), сжать его или в лог записать, сколько времени он там бултыхались.
А зачем это всё, спрашивается? Ну вот, блядь, преимущества:
- Не повторяйся, мудила! Вместо того чтобы в КАЖДОЙ view-функции писать одну и ту же проверку на авторизацию или логирование, ты пишешь это один раз в middleware — и оно работает на все роуты автоматом. Красота, ёпта!
- Всё по полочкам. Аутентификация, логи, обработка ошибок, CORS, сжатие ответов — всё это можно вынести в отдельные middleware-компоненты. Получается как конструктор: нужна аутентификация — добавил компонент, не нужна — выкинул. Никакой головной боли с основной бизнес-логикой.
- Центр управления полётами. Вся общая, скучная, но необходимая хуйня живёт в одном месте, а не размазана по всему проекту. Подозрение ебать чувствую, что без этого жить можно, но с ним — как-то спокойнее.
Короче, middleware — это как умный привратник в твоём приложении. Он может и пропустить, и не пустить, и записать кто приходил, и даже ответ немного подправить перед отправкой. Хуй с горы, а не инструмент!