Перейти до змісту

Middleware (Проміжний шар)

У FastAPI можна додавати middleware (проміжний шар).

"Middleware" — це функція, яка працює з кожним запитом перед його обробкою будь-якою конкретною операцією шляху (path operation), а також з кожною відповіддю перед її поверненням.

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

Технічні деталі

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

Якщо були заплановані фонові задачі (background tasks - розглянуто далі), вони виконаються після всіх middleware.

Створення middleware

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

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

  • Запит.
  • Функцію call_next, яка приймає запит як параметр.

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

import time

from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.perf_counter()
    response = await call_next(request)
    process_time = time.perf_counter() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Порада

Не забувайте, що власні заголовки можна додавати, використовуючи префікс 'X-'.

Але якщо у Вас є власні заголовки, які Ви хочете, щоб браузерний клієнт міг побачити, потрібно додати їх до Вашої конфігурації CORS (див. CORS (Обмін ресурсами між різними джерелами) за допомогою параметра expose_headers, описаного в документації Starlette по CORS.

Технічні деталі

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

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

До і після response(відповіді)

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

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

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

import time

from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.perf_counter()
    response = await call_next(request)
    process_time = time.perf_counter() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Підказка

Тут ми використовуємо time.perf_counter() замість time.time() оскільки він може бути більш точним для таких випадків. 🤓

Інші middlewares

Ви можете пізніше прочитати більше про інші middlewares в Advanced User Guide: Advanced Middleware.

Ви дізнаєтесь, як обробляти CORS за допомогою middleware в наступному розділі.