Ответ
Основным паттерном проектирования для реализации middleware является Цепочка обязанностей (Chain of Responsibility).
Этот паттерн позволяет выстраивать компоненты (middleware) в последовательную цепь. Каждый компонент получает запрос, выполняет свою логику и либо передает управление следующему компоненту в цепочке, либо возвращает ответ, прерывая дальнейшую обработку.
Почему это удобно для middleware:
- Разделение ответственности: Каждый компонент решает одну конкретную задачу (аутентификация, логирование, кэширование).
- Гибкость: Порядок компонентов в цепочке можно легко изменять.
- Переиспользование: Компоненты можно использовать в разных частях приложения.
Концептуальный пример на Python:
class Middleware:
def __init__(self, next_handler=None):
self._next_handler = next_handler
def handle(self, request):
# Логика ДО обработки следующим компонентом
if self._next_handler:
return self._next_handler.handle(request)
# Базовый случай: конец цепочки
return request
class AuthenticationMiddleware(Middleware):
def handle(self, request):
print("1. Проверка аутентификации...")
if not request.get("user"):
return {"error": "Unauthorized"} # Прерываем цепочку
return super().handle(request)
class LoggingMiddleware(Middleware):
def handle(self, request):
print("2. Логирование запроса...")
response = super().handle(request)
print("4. Логирование ответа...")
return response
# Сборка цепочки (выполняется в обратном порядке)
# Logging -> Authentication -> CoreLogic
chain = LoggingMiddleware(AuthenticationMiddleware())
# Симуляция запроса
request = {"user": "admin", "data": "payload"}
# Запуск обработки
# Вывод:
# 1. Проверка аутентификации...
# 2. Логирование запроса...
# 4. Логирование ответа...
response = chain.handle(request)
Также в реализации middleware могут применяться элементы паттерна Декоратор, особенно во фреймворках вроде FastAPI, где middleware оборачивает вызов эндпоинта.
Ответ 18+ 🔞
Да ты посмотри, какой у нас тут паттерн-то главный для middleware вылез — Цепочка обязанностей, ёпта! Ну реально, как в жизни: один за другого цепляется, и пошла плясать губерния.
А удобно-то как, блядь:
- Разделили ответственность — каждый занимается своим делом, не лезет в чужую тарелку. Один логи пишет, другой права проверяет, третий кэш ебёт.
- Гибкость — хочешь, сначала авторизацию гони, хочешь — логирование. Переставляй, как кубики, сука.
- Переиспользование — написал один раз, вставил куда надо, и нехуй изобретать велосипед.
Вот смотри, как это на Питоне выглядит, только не засыпай, а то хуй потом разбудишь:
class Middleware:
def __init__(self, next_handler=None):
self._next_handler = next_handler
def handle(self, request):
# Тут делаем что-то ДО того, как следующий в цепочке вмажет свою логику
if self._next_handler:
return self._next_handler.handle(request)
# Если дальше некому передавать — конец, приехали
return request
class AuthenticationMiddleware(Middleware):
def handle(self, request):
print("1. Проверка аутентификации...")
if not request.get("user"):
return {"error": "Unauthorized"} # Тут цепочку рвём нахуй
return super().handle(request)
class LoggingMiddleware(Middleware):
def handle(self, request):
print("2. Логирование запроса...")
response = super().handle(request)
print("4. Логирование ответа...")
return response
# Собираем цепь, как паровозик. Собирается с конца, блядь, внимание!
# Получается: Logging -> Authentication -> CoreLogic
chain = LoggingMiddleware(AuthenticationMiddleware())
# Запрос симулируем
request = {"user": "admin", "data": "payload"}
# Поехали обрабатывать!
# На экране будет:
# 1. Проверка аутентификации...
# 2. Логирование запроса...
# 4. Логирование ответа...
response = chain.handle(request)
А ещё, сука, в некоторых фреймворках, типа FastAPI, middleware может через Декоратор реализовываться — там просто оборачивают вызов эндпоинта, как одеялом, и всё. Красота, блядь, а не жизнь!