Какой основной паттерн проектирования используется для реализации middleware?

Ответ

Основным паттерном проектирования для реализации 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 может через Декоратор реализовываться — там просто оборачивают вызов эндпоинта, как одеялом, и всё. Красота, блядь, а не жизнь!