Перейти к основному содержимому

Код вокруг каждого обработчика

Промежуточный слой (middleware) — это код, который выполняется вокруг ваших обработчиков: до того, как запрос дойдёт до них, после того, как ответ покинет их, или вместо них. Логирование, аутентификация, ограничение частоты запросов, сжатие — всё это промежуточные слои.

Одна и та же идея встречается под тремя названиями: веб-фреймворки говорят middleware, gRPC говорит interceptor, некоторые экосистемы говорят filter. Одно понятие — три словаря.

В Python промежуточный слой — это функция, которая принимает функцию-обработчик и возвращает обёрнутую — именно для этого и создан собственный синтаксис Python @decorator, и это в точности паттерн Декоратор из группы паттернов проектирования. Стопка таких слоёв ведёт себя как Цепочка обязанностей.


Промежуточный слой для логирования

with_log оборачивает любую функцию-обработчик: выводит входящий запрос, даёт обработчику выполнить работу и снова выводит строку на выходе. Сам обработчик об этом ничего не знает. functools.wraps сохраняет видимыми имя и документацию обёрнутой функции — это тот же помощник, который использует каждый декоратор в Python.

Обернуть один раз — логировать всё

Обёрнутый обработчик обслуживает два разных пути, и оба попадают в лог — логирование написано один раз, в обёртке, а не в каждом обработчике.

Prompt
Напиши программу на Python с промежуточным слоем (middleware) with_log, который оборачивает функцию-обработчик: перед её вызовом выводит строку со стрелкой, методом и путём, а после — строку о завершении. Оберни функцию app, которая обслуживает два пути, запусти её на свободном порту, запроси оба пути и выведи ответы.
Вывод: полная программа на Python
Wrap once, log everything

Промежуточный слой, который останавливает запрос

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

В цепочке with_log(with_auth(report)) запрос проходит через слои по порядку — а ответ всплывает обратно через них же.

Слой аутентификации в цепочке

Запрос без ключа останавливается слоем аутентификации с кодом 401 — обработчик так и не запускается. С ключом запрос проходит всю цепочку и добирается до данных.

Prompt
Напиши программу на Python с двумя связанными в цепочку промежуточными слоями (middleware): with_log, который выводит запрос, и with_auth, который проверяет заголовок X-API-Key и, если ключ неверный, отвечает 401, не вызывая следующий обработчик. Оберни обработчик как with_log(with_auth(report)), запусти сервер на свободном порту, затем отправь один запрос без ключа и один с ключом и выведи коды состояния и тела обоих ответов.
Вывод: полная программа на Python