# Користувацька відповідь - HTML, стрім, файл, інше { #custom-response-html-stream-file-others }
Типово **FastAPI** повертатиме JSON-відповіді.
Ви можете переписати це, повернувши `Response` безпосередньо, як показано в [Повернути відповідь безпосередньо](response-directly.md).
Але якщо ви повертаєте `Response` безпосередньо (або будь-який його підклас, як-от `JSONResponse`), дані не будуть автоматично конвертовані (навіть якщо ви оголосите `response_model`), і документація не буде автоматично згенерована (наприклад, з включенням конкретного «медіа-типу» в HTTP-заголовку `Content-Type` як частини згенерованого OpenAPI).
Ви також можете оголосити `Response`, який слід використовувати (наприклад, будь-який підклас `Response`), у декораторі операції шляху через параметр `response_class`.
Вміст, який ви повертаєте з вашої функції операції шляху, буде поміщений усередину цього `Response`.
/// note | Примітка
Якщо ви використовуєте клас відповіді без медіа-типу, FastAPI очікуватиме, що у вашої відповіді не буде вмісту, тож формат відповіді не буде задокументовано в згенерованій документації OpenAPI.
///
## JSON-відповіді { #json-responses }
Типово FastAPI повертає JSON-відповіді.
Якщо ви оголосите [Модель відповіді](../tutorial/response-model.md), FastAPI використає її, щоб серіалізувати дані в JSON за допомогою Pydantic.
Якщо ви не оголосите модель відповіді, FastAPI використає `jsonable_encoder`, пояснений у [Сумісний кодувальник JSON](../tutorial/encoder.md), і помістить результат у `JSONResponse`.
Якщо ви оголосите `response_class` з JSON медіа-типом (`application/json`), як у випадку з `JSONResponse`, дані, що повертаються, будуть автоматично перетворені (і відфільтровані) згідно з будь-якою Pydantic `response_model`, яку ви оголосили в декораторі операції шляху. Але дані не будуть серіалізовані в JSON-байти за допомогою Pydantic, натомість вони будуть перетворені з `jsonable_encoder`, а потім передані класу `JSONResponse`, який і серіалізує їх у байти, використовуючи стандартну JSON-бібліотеку в Python.
### Продуктивність JSON { #json-performance }
Коротко: якщо вам потрібна максимальна продуктивність, використовуйте [Модель відповіді](../tutorial/response-model.md) і не оголошуйте `response_class` у декораторі операції шляху.
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML-відповідь { #html-response }
Щоб повернути відповідь із HTML безпосередньо з **FastAPI**, використовуйте `HTMLResponse`.
- Імпортуйте `HTMLResponse`.
- Передайте `HTMLResponse` як параметр `response_class` вашого декоратора операції шляху.
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info | Інформація
Параметр `response_class` також визначатиме «медіа-тип» відповіді.
У цьому випадку HTTP-заголовок `Content-Type` буде встановлено в `text/html`.
І це буде задокументовано відповідно в OpenAPI.
///
### Повернути `Response` { #return-a-response }
Як показано в [Повернути відповідь безпосередньо](response-directly.md), ви також можете переписати відповідь безпосередньо у вашій операції шляху, просто повернувши її.
Той самий приклад вище, що повертає `HTMLResponse`, може виглядати так:
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning | Попередження
`Response`, повернений безпосередньо вашою функцією операції шляху, не буде задокументовано в OpenAPI (наприклад, `Content-Type` не буде задокументовано) і не буде видно в автоматичній інтерактивній документації.
///
/// info | Інформація
Звісно, фактичні заголовок `Content-Type`, код статусу тощо прийдуть з об'єкта `Response`, який ви повернули.
///
### Задокументуйте в OpenAPI і перепишіть `Response` { #document-in-openapi-and-override-response }
Якщо ви хочете переписати відповідь усередині функції, але водночас задокументувати «медіа-тип» в OpenAPI, ви можете використати параметр `response_class` І повернути об'єкт `Response`.
Тоді `response_class` буде використано лише для документування операції шляху в OpenAPI, а ваша `Response` буде використана як є.
#### Повернути `HTMLResponse` безпосередньо { #return-an-htmlresponse-directly }
Наприклад, це може бути щось на кшталт:
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
У цьому прикладі функція `generate_html_response()` уже генерує та повертає `Response` замість повернення HTML як `str`.
Повертаючи результат виклику `generate_html_response()`, ви вже повертаєте `Response`, яка перепише типову поведінку **FastAPI**.
Але оскільки ви також передали `HTMLResponse` у `response_class`, **FastAPI** знатиме, як задокументувати це в OpenAPI та інтерактивній документації як HTML з `text/html`:
## Доступні відповіді { #available-responses }
Ось деякі з доступних відповідей.
Майте на увазі, що ви можете використовувати `Response`, щоб повертати що завгодно інше, або навіть створити власний підклас.
/// note | Технічні деталі
Ви також можете використати `from starlette.responses import HTMLResponse`.
**FastAPI** надає ті ж `starlette.responses` як `fastapi.responses` лише для вашої зручності як розробника. Але більшість доступних відповідей надходять безпосередньо зі Starlette.
///
### `Response` { #response }
Головний клас `Response`, від якого успадковуються всі інші відповіді.
Ви можете повертати його безпосередньо.
Він приймає такі параметри:
- `content` - `str` або `bytes`.
- `status_code` - `int` - код статусу HTTP.
- `headers` - `dict` строк.
- `media_type` - `str`, що задає медіа-тип, напр. `"text/html"`.
FastAPI (насправді Starlette) автоматично додасть заголовок Content-Length. Також буде додано заголовок Content-Type на основі `media_type` з додаванням набору символів для текстових типів.
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
Приймає текст або байти та повертає HTML-відповідь, як описано вище.
### `PlainTextResponse` { #plaintextresponse }
Приймає текст або байти та повертає відповідь звичайним текстом.
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
Приймає дані та повертає відповідь, закодовану як `application/json`.
Це типова відповідь, яку використовує **FastAPI**, як зазначено вище.
/// note | Технічні деталі
Але якщо ви оголосите модель відповіді або тип, його буде використано безпосередньо для серіалізації даних у JSON, і відповідь з коректним медіа-типом для JSON буде повернута безпосередньо, без використання класу `JSONResponse`.
Це ідеальний спосіб отримати найкращу продуктивність.
///
### `RedirectResponse` { #redirectresponse }
Повертає HTTP-перенаправлення. Типово використовує код статусу 307 (Temporary Redirect).
Ви можете повернути `RedirectResponse` безпосередньо:
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
Або ви можете використати його в параметрі `response_class`:
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
У такому разі ви можете повертати URL безпосередньо з вашої функції операції шляху.
У цьому випадку `status_code` буде типовим для `RedirectResponse`, тобто `307`.
---
Ви також можете використати параметр `status_code` разом із параметром `response_class`:
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
Приймає async-генератор або звичайний генератор/ітератор (функцію з `yield`) і потоково передає тіло відповіді.
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
/// note | Технічні деталі
Завдання `async` може бути скасовано лише тоді, коли воно досягає `await`. Якщо немає `await`, генератор (функція з `yield`) не може бути коректно скасований і може продовжувати працювати навіть після запиту на скасування.
Оскільки цьому невеликому прикладу не потрібні жодні оператори `await`, ми додаємо `await anyio.sleep(0)`, щоб надати циклу подій шанс обробити скасування.
Це ще важливіше для великих або нескінченних потоків.
///
/// tip | Порада
Замість того щоб повертати `StreamingResponse` безпосередньо, імовірно, краще дотримуватися стилю в [Потокова передача даних](./stream-data.md), це значно зручніше та обробляє скасування «за лаштунками» для вас.
Якщо ви транслюєте JSON Lines, дотримуйтесь навчального посібника [Потоки JSON Lines](../tutorial/stream-json-lines.md).
///
### `FileResponse` { #fileresponse }
Асинхронно транслює файл як відповідь.
Приймає інший набір аргументів для створення екземпляра, ніж інші типи відповідей:
- `path` - шлях до файлу для трансляції.
- `headers` - будь-які користувацькі заголовки як словник.
- `media_type` - строка, що задає медіа-тип. Якщо не встановлено, медіа-тип буде виведено з імені файлу або шляху.
- `filename` - якщо встановлено, буде включено до `Content-Disposition` відповіді.
Відповіді з файлами включатимуть відповідні заголовки `Content-Length`, `Last-Modified` і `ETag`.
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
Ви також можете використати параметр `response_class`:
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
У цьому випадку ви можете повертати шлях до файлу безпосередньо з вашої функції операції шляху.
## Власний клас відповіді { #custom-response-class }
Ви можете створити власний клас відповіді, успадкувавши його від `Response`, і використовувати його.
Наприклад, скажімо, ви хочете використовувати [`orjson`](https://github.com/ijl/orjson) з деякими налаштуваннями.
Припустімо, ви хочете, щоб повертався відформатований із відступами JSON, тож ви хочете використати опцію orjson `orjson.OPT_INDENT_2`.
Ви можете створити `CustomORJSONResponse`. Головне, що потрібно зробити, це створити метод `Response.render(content)`, який повертає вміст як `bytes`:
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
Тепер замість повернення:
```json
{"message": "Hello World"}
```
...ця відповідь повертатиме:
```json
{
"message": "Hello World"
}
```
Звісно, ви, ймовірно, знайдете значно кращі способи скористатися цим, ніж просто форматування JSON. 😉
### `orjson` або Модель відповіді { #orjson-or-response-model }
Якщо ви шукаєте продуктивність, імовірно, краще використати [Модель відповіді](../tutorial/response-model.md), ніж відповідь `orjson`.
З моделлю відповіді FastAPI використає Pydantic, щоб серіалізувати дані в JSON без проміжних кроків, як-от перетворення за допомогою `jsonable_encoder`, що відбувалося б в іншому випадку.
І «під капотом» Pydantic використовує ті самі внутрішні механізми Rust, що й `orjson`, для серіалізації в JSON, тож ви вже отримаєте найкращу продуктивність із моделлю відповіді.
## Типова відповідь за замовчуванням { #default-response-class }
Створюючи екземпляр класу **FastAPI** або `APIRouter`, ви можете вказати, який клас відповіді використовувати за замовчуванням.
Параметр, що це визначає, - `default_response_class`.
У прикладі нижче **FastAPI** використовуватиме `HTMLResponse` за замовчуванням в усіх операціях шляху, замість JSON.
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip | Порада
Ви все одно можете переписати `response_class` в операціях шляху, як і раніше.
///
## Додаткова документація { #additional-documentation }
Ви також можете оголосити медіа-тип і багато інших деталей в OpenAPI, використовуючи `responses`: [Додаткові відповіді в OpenAPI](additional-responses.md).