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