6.1 KiB
Middleware (Промежуточный слой)
Вы можете добавить middleware (промежуточный слой) в FastAPI приложение.
"Middleware" - это функция, которая выполняется с каждым запросом до его обработки какой-либо конкретной операцией пути. А также с каждым ответом перед его возвращением.
- Она принимает каждый поступающий запрос.
- Может что-то сделать с этим запросом или выполнить любой нужный код.
- Затем передает запрос для последующей обработки (какой-либо операцией пути).
- Получает ответ (от операции пути).
- Может что-то сделать с этим ответом или выполнить любой нужный код.
- И возвращает ответ.
/// note | Технические детали
Если у вас есть зависимости с yield, то код выхода (код после yield) будет выполняться после middleware.
Если были какие‑либо фоновые задачи (рассматриваются в разделе Фоновые задачи, вы увидите это позже), они будут запущены после всех middleware.
///
Создание middleware
Для создания middleware используйте декоратор @app.middleware("http") поверх функции.
Функция middleware получает:
request.- Функцию
call_next, которая получаетrequestв качестве параметра.- Эта функция передаёт
requestсоответствующей операции пути. - Затем она возвращает
response, сгенерированный соответствующей операцией пути.
- Эта функция передаёт
- Также имеется возможность видоизменить
responseперед тем как его вернуть.
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip | Совет
Имейте в виду, что можно добавлять проприетарные HTTP-заголовки с префиксом X-.
Но если вы хотите, чтобы клиент в браузере мог видеть ваши пользовательские заголовки, необходимо добавить их в настройки CORS (CORS (Cross-Origin Resource Sharing)), используя параметр expose_headers, описанный в документации по CORS Starlette.
///
/// note | Технические детали
Вы также можете использовать from starlette.requests import Request.
FastAPI предоставляет такой доступ для удобства разработчиков. Но, на самом деле, это Request из Starlette.
///
До и после response
Вы можете добавить код, использующий request, до передачи его какой-либо операции пути.
А также после формирования response, до того, как вы его вернёте.
Например, вы можете добавить собственный заголовок X-Process-Time, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip | Совет
Мы используем time.perf_counter() вместо time.time() для обеспечения большей точности в таких случаях. 🤓
///
Порядок выполнения нескольких middleware
Когда вы добавляете несколько middleware с помощью декоратора @app.middleware() или метода app.add_middleware(), каждое новое middleware оборачивает приложение, формируя стек. Последнее добавленное middleware — самое внешнее (outermost), а первое — самое внутреннее (innermost).
На пути обработки запроса сначала выполняется самое внешнее middleware.
На пути формирования ответа оно выполняется последним.
Например:
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
Это приводит к следующему порядку выполнения:
-
Запрос: MiddlewareB → MiddlewareA → маршрут
-
Ответ: маршрут → MiddlewareA → MiddlewareB
Такое стековое поведение обеспечивает предсказуемый и управляемый порядок выполнения middleware.
Другие middleware
О других middleware вы можете узнать больше в разделе Расширенное руководство пользователя: Продвинутое middleware.
В следующем разделе вы можете прочитать, как настроить CORS с помощью middleware.