# Тіло запиту { #request-body }

Коли вам потрібно надіслати дані з клієнта (скажімо, браузера) до вашого API, ви надсилаєте їх як **тіло запиту**.

Тіло **запиту** - це дані, надіслані клієнтом до вашого API. Тіло **відповіді** - це дані, які ваш API надсилає клієнту.

Ваш API майже завжди має надсилати тіло **відповіді**. Але клієнтам не обов’язково потрібно постійно надсилати тіла **запитів** — інколи вони лише запитують шлях, можливо з деякими параметрами запиту, але не надсилають тіло.

Щоб оголосити тіло **запиту**, ви використовуєте [Pydantic](https://docs.pydantic.dev/) моделі з усією їх потужністю та перевагами.

/// info | Інформація

Щоб надіслати дані, ви повинні використовувати один із: `POST` (більш поширений), `PUT`, `DELETE` або `PATCH`.

Надсилання тіла із запитом `GET` має невизначену поведінку в специфікаціях, проте воно підтримується FastAPI лише для дуже складних/екстремальних випадків використання.

Оскільки це не рекомендується, інтерактивна документація з Swagger UI не відображатиме документацію для тіла запиту під час використання `GET`, і проксі-сервери в середині можуть не підтримувати її.

///

## Імпортуйте `BaseModel` від Pydantic { #import-pydantics-basemodel }

Спочатку вам потрібно імпортувати `BaseModel` з `pydantic`:

{* ../../docs_src/body/tutorial001_py310.py hl[2] *}

## Створіть свою модель даних { #create-your-data-model }

Потім ви оголошуєте свою модель даних як клас, який успадковується від `BaseModel`.

Використовуйте стандартні типи Python для всіх атрибутів:

{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}


Так само, як і при оголошенні параметрів запиту, коли атрибут моделі має значення за замовчуванням, він не є обов’язковим. В іншому випадку це потрібно. Використовуйте `None`, щоб зробити його просто необов'язковим.

Наприклад, ця модель вище оголошує JSON "`об'єкт`" (або Python `dict`), як:

```JSON
{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}
```

...оскільки `description` і `tax` є необов'язковими (зі значенням за замовчуванням `None`), цей JSON "`об'єкт`" також буде дійсним:

```JSON
{
    "name": "Foo",
    "price": 45.2
}
```

## Оголосіть її як параметр { #declare-it-as-a-parameter }

Щоб додати модель даних до вашої *операції шляху*, оголосіть її так само, як ви оголосили параметри шляху та запиту:

{* ../../docs_src/body/tutorial001_py310.py hl[16] *}

...і вкажіть її тип як модель, яку ви створили, `Item`.

## Результати { #results }

Лише з цим оголошенням типу Python **FastAPI** буде:

* Читати тіло запиту як JSON.
* Перетворювати відповідні типи (якщо потрібно).
* Валідувати дані.
    * Якщо дані недійсні, він поверне гарну та чітку помилку, вказуючи, де саме і які дані були неправильними.
* Надавати отримані дані у параметрі `item`.
    * Оскільки ви оголосили його у функції як тип `Item`, ви також матимете всю підтримку редактора (автозаповнення, тощо) для всіх атрибутів та їх типів.
* Генерувати визначення [Схеми JSON](https://json-schema.org) для вашої моделі, ви також можете використовувати їх де завгодно, якщо це має сенс для вашого проекту.
* Ці схеми будуть частиною згенерованої схеми OpenAPI і використовуватимуться автоматичною документацією <abbr title="User Interfaces - Інтерфейси користувача">UIs</abbr>.

## Автоматична документація { #automatic-docs }

Схеми JSON ваших моделей будуть частиною вашої схеми, згенерованої OpenAPI, і будуть показані в інтерактивній API документації:

<img src="/img/tutorial/body/image01.png">

А також використовуватимуться в API документації всередині кожної *операції шляху*, якій вони потрібні:

<img src="/img/tutorial/body/image02.png">

## Підтримка редактора { #editor-support }

У вашому редакторі, всередині вашої функції, ви будете отримувати підказки типу та завершення скрізь (це б не сталося, якби ви отримали `dict` замість моделі Pydantic):

<img src="/img/tutorial/body/image03.png">

Ви також отримуєте перевірку помилок на наявність операцій з неправильним типом:

<img src="/img/tutorial/body/image04.png">

Це не випадково, весь каркас був побудований навколо цього дизайну.

І він був ретельно перевірений на етапі проектування, перед будь-яким впровадженням, щоб переконатися, що він працюватиме з усіма редакторами.

Були навіть деякі зміни в самому Pydantic, щоб підтримати це.

Попередні скріншоти були зроблені у [Visual Studio Code](https://code.visualstudio.com).

Але ви отримаєте ту саму підтримку редактора у [PyCharm](https://www.jetbrains.com/pycharm/) та більшість інших редакторів Python:

<img src="/img/tutorial/body/image05.png">

/// tip | Порада

Якщо ви використовуєте [PyCharm](https://www.jetbrains.com/pycharm/) як ваш редактор, ви можете використати [Pydantic PyCharm Plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin/).

Він покращує підтримку редакторів для моделей Pydantic за допомогою:

* автозаповнення
* перевірки типу
* рефакторингу
* пошуку
* інспекції

///

## Використовуйте модель { #use-the-model }

Усередині функції ви можете отримати прямий доступ до всіх атрибутів об’єкта моделі:

{* ../../docs_src/body/tutorial002_py310.py *}

## Тіло запиту + параметри шляху { #request-body-path-parameters }

Ви можете одночасно оголошувати параметри шляху та тіло запиту.

**FastAPI** розпізнає, що параметри функції, які відповідають параметрам шляху, мають бути **взяті з шляху**, а параметри функції, які оголошуються як моделі Pydantic, **взяті з тіла запиту**.

{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}


## Тіло запиту + шлях + параметри запиту { #request-body-path-query-parameters }

Ви також можете оголосити параметри **тіло**, **шлях** і **запит** одночасно.

**FastAPI** розпізнає кожен з них і візьме дані з потрібного місця.

{* ../../docs_src/body/tutorial004_py310.py hl[16] *}

Параметри функції будуть розпізнаватися наступним чином:

* Якщо параметр також оголошено в **шляху**, він використовуватиметься як параметр шляху.
* Якщо параметр має **сингулярний тип** (наприклад, `int`, `float`, `str`, `bool` тощо), він буде інтерпретуватися як параметр **запиту**.
* Якщо параметр оголошується як тип **Pydantic моделі**, він інтерпретується як **тіло** **запиту**.

/// note | Примітка

FastAPI буде знати, що значення `q` не є обов'язковим через значення за замовчуванням `= None`.

`str | None` FastAPI не використовує, щоб визначити, що значення не є обов’язковим - він знатиме, що воно не є обов’язковим, тому що має значення за замовчуванням `= None`.

Але додавання анотацій типів дозволить вашому редактору надати вам кращу підтримку та виявляти помилки.

///

## Без Pydantic { #without-pydantic }

Якщо ви не хочете використовувати моделі Pydantic, ви також можете використовувати параметри **Body**. Перегляньте документацію для [Тіло - Кілька параметрів: Окремі значення в тілі](body-multiple-params.md#singular-values-in-body).
