# Middleware { #middleware }

У **FastAPI** можна додавати middleware.

«Middleware» — це функція, яка працює з кожним **запитом** перед його обробкою будь-якою конкретною *операцією шляху*. А також з кожною **відповіддю** перед її поверненням.

* Вона отримує кожен **запит**, що надходить до вашого застосунку.
* Потім вона може виконати певні дії із цим **запитом** або запустити необхідний код.
* Далі вона передає **запит** для обробки рештою застосунку (якоюсь *операцією шляху*).
* Потім вона отримує **відповідь**, сформовану застосунком (якоюсь *операцією шляху*).
* Вона може виконати певні дії із цією **відповіддю** або запустити необхідний код.
* Потім вона повертає **відповідь**.

/// note | Технічні деталі

Якщо у вас є залежності з `yield`, код виходу виконається *після* middleware.

Якщо були заплановані фонові задачі (розглянуто в розділі [Background Tasks](background-tasks.md){.internal-link target=_blank}, ви побачите це пізніше), вони виконаються *після* всіх middleware.

///

## Створення middleware { #create-a-middleware }

Щоб створити middleware, ви використовуєте декоратор `@app.middleware("http")` над функцією.

Функція middleware отримує:

* `request`.
* Функцію `call_next`, яка отримає `request` як параметр.
    * Ця функція передасть `request` відповідній *операції шляху*.
    * Потім вона поверне `response`, згенеровану відповідною *операцією шляху*.
* Потім ви можете додатково змінити `response` перед тим, як повернути її.

{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}

/// tip | Порада

Пам’ятайте, що власні пропрієтарні заголовки можна додавати <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">використовуючи префікс `X-`</a>.

Але якщо у вас є власні заголовки, які ви хочете, щоб клієнт у браузері міг побачити, потрібно додати їх до ваших конфігурацій CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}) за допомогою параметра `expose_headers`, описаного в <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">документації Starlette по CORS</a>.

///

/// note | Технічні деталі

Ви також можете використати `from starlette.requests import Request`.

**FastAPI** надає це для вашої зручності як розробника. Але воно походить безпосередньо зі Starlette.

///

### До і після `response` { #before-and-after-the-response }

Ви можете додати код, який буде виконуватися з `request`, до того, як його отримає будь-яка *операція шляху*.

Також ви можете додати код, який буде виконуватися після того, як `response` буде згенеровано, перед тим як її повернути.

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

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

/// tip | Порада

Тут ми використовуємо <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> замість `time.time()` оскільки він може бути більш точним для таких випадків. 🤓

///

## Порядок виконання кількох middleware { #multiple-middleware-execution-order }

Коли ви додаєте кілька middleware, використовуючи або декоратор `@app.middleware()` або метод `app.add_middleware()`, кожен новий middleware обгортає застосунок, утворюючи стек. Останній доданий middleware є *зовнішнім*, а перший — *внутрішнім*.

На шляху запиту першим виконується *зовнішній* middleware.

На шляху відповіді він виконується останнім.

Наприклад:

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

Це призводить до такого порядку виконання:

* **Запит**: MiddlewareB → MiddlewareA → route

* **Відповідь**: route → MiddlewareA → MiddlewareB

Така поведінка стеку гарантує, що middleware виконуються у передбачуваному та керованому порядку.

## Інші middlewares { #other-middlewares }

Ви можете пізніше прочитати більше про інші middlewares в [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.

Ви дізнаєтесь, як обробляти <abbr title="Cross-Origin Resource Sharing">CORS</abbr> за допомогою middleware в наступному розділі.
