# Middleware (Промежуточный слой) { #middleware }

Вы можете добавить middleware (промежуточный слой) в **FastAPI** приложение.

"Middleware" - это функция, которая выполняется с каждым **запросом** до его обработки какой-либо конкретной *операцией пути*. А также с каждым **ответом** перед его возвращением.

* Она принимает каждый поступающий **запрос**.
* Может что-то сделать с этим **запросом** или выполнить любой нужный код.
* Затем передает **запрос** для последующей обработки (какой-либо *операцией пути*).
* Получает **ответ** (от *операции пути*).
* Может что-то сделать с этим **ответом** или выполнить любой нужный код.
* И возвращает **ответ**.

/// note | Технические детали

Если у вас есть зависимости с `yield`, то код выхода (код после `yield`) будет выполняться *после* middleware.

Если были какие‑либо фоновые задачи (рассматриваются в разделе [Фоновые задачи](background-tasks.md), вы увидите это позже), они будут запущены *после* всех middleware.

///

## Создание middleware { #create-a-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-`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers).

Но если вы хотите, чтобы клиент в браузере мог видеть ваши пользовательские заголовки, необходимо добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md)), используя параметр `expose_headers`, описанный в [документации по CORS Starlette](https://www.starlette.dev/middleware/#corsmiddleware).

///

/// note | Технические детали

Вы также можете использовать `from starlette.requests import Request`.

**FastAPI** предоставляет такой доступ для удобства разработчиков. Но, на самом деле, это `Request` из Starlette.

///

### До и после `response` { #before-and-after-the-response }

Вы можете добавить код, использующий `request`, до передачи его какой-либо *операции пути*.

А также после формирования `response`, до того, как вы его вернёте.

Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:

{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}

/// tip | Совет

Мы используем [`time.perf_counter()`](https://docs.python.org/3/library/time.html#time.perf_counter) вместо `time.time()` для обеспечения большей точности в таких случаях. 🤓

///

## Порядок выполнения нескольких middleware { #multiple-middleware-execution-order }

Когда вы добавляете несколько middleware с помощью декоратора `@app.middleware()` или метода `app.add_middleware()`, каждое новое middleware оборачивает приложение, формируя стек. Последнее добавленное middleware — самое внешнее (*outermost*), а первое — самое внутреннее (*innermost*).

На пути обработки запроса сначала выполняется самое внешнее middleware.

На пути формирования ответа оно выполняется последним.

Например:

```Python
app.add_middleware(MiddlewareA)
app.add_middleware(MiddlewareB)
```

Это приводит к следующему порядку выполнения:

* **Запрос**: MiddlewareB → MiddlewareA → маршрут

* **Ответ**: маршрут → MiddlewareA → MiddlewareB

Такое стековое поведение обеспечивает предсказуемый и управляемый порядок выполнения middleware.

## Другие middleware { #other-middlewares }

О других middleware вы можете узнать больше в разделе [Расширенное руководство пользователя: Продвинутое middleware](../advanced/middleware.md).

В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing - совместное использование ресурсов между источниками">CORS</abbr> с помощью middleware.
