# Користувацька відповідь - 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`:

<img src="/img/tutorial/custom-response/image01.png">

## Доступні відповіді { #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).
