# Альтернативи, натхнення та порівняння

Що надихнуло на створення **FastAPI**, який він у порінянні з іншими альтернативами та чого він у них навчився.

## Вступ

**FastAPI** не існувало б, якби не попередні роботи інших.

Раніше було створено багато інструментів, які надихнули на його створення.

Я кілька років уникав створення нового фреймворку. Спочатку я спробував вирішити всі функції, охоплені **FastAPI**, використовуючи багато різних фреймворків, плагінів та інструментів.

Але в якийсь момент не було іншого виходу, окрім створення чогось, що надавало б усі ці функції, взявши найкращі ідеї з попередніх інструментів і поєднавши їх найкращим чином, використовуючи мовні функції, які навіть не були доступні раніше (Python 3.6+ підказки типів).

## Попередні інструменти

### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a>

Це найпопулярніший фреймворк Python, який користується широкою довірою. Він використовується для створення таких систем, як Instagram.

Він відносно тісно пов’язаний з реляційними базами даних (наприклад, MySQL або PostgreSQL), тому мати базу даних NoSQL (наприклад, Couchbase, MongoDB, Cassandra тощо) як основний механізм зберігання не дуже просто.

Він був створений для створення HTML у серверній частині, а не для створення API, які використовуються сучасним інтерфейсом (як-от React, Vue.js і Angular) або іншими системами (як-от <abbr title="Internet of Things">IoT</abbr > пристрої), які спілкуються з ним.

### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a>

Фреймворк Django REST був створений як гнучкий інструментарій для створення веб-інтерфейсів API використовуючи Django в основі, щоб покращити його можливості API.

Його використовують багато компаній, включаючи Mozilla, Red Hat і Eventbrite.

Це був один із перших прикладів **автоматичної документації API**, і саме це була одна з перших ідей, яка надихнула на «пошук» **FastAPI**.

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

Django REST Framework створив Том Крісті. Той самий творець Starlette і Uvicorn, на яких базується **FastAPI**.

///

/// check | Надихнуло **FastAPI** на

Мати автоматичний веб-інтерфейс документації API.

///

### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a>

Flask — це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django.

Ця простота та гнучкість дозволяють використовувати бази даних NoSQL як основну систему зберігання даних.

Оскільки він дуже простий, він порівняно легкий та інтуїтивний для освоєння, хоча в деяких моментах документація стає дещо технічною.

Він також зазвичай використовується для інших програм, яким не обов’язково потрібна база даних, керування користувачами або будь-яка з багатьох функцій, які є попередньо вбудованими в Django. Хоча багато з цих функцій можна додати за допомогою плагінів.

Відокремлення частин було ключовою особливістю, яку я хотів зберегти, при цьому залишаючись «мікрофреймворком», який можна розширити, щоб охопити саме те, що потрібно.

Враховуючи простоту Flask, він здавався хорошим підходом для створення API. Наступним, що знайшов, був «Django REST Framework» для Flask.

/// check | Надихнуло **FastAPI** на

Бути мікрофреймоворком. Зробити легким комбінування та поєднання необхідних інструментів та частин.

 Мати просту та легку у використанні систему маршрутизації.

///

### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a>

**FastAPI** насправді не є альтернативою **Requests**. Сфера їх застосування дуже різна.

Насправді цілком звична річ використовувати Requests *всередині* програми FastAPI.

Але все ж FastAPI черпав натхнення з Requests.

**Requests** — це бібліотека для *взаємодії* з API (як клієнт), а **FastAPI** — це бібліотека для *створення* API (як сервер).

Вони більш-менш знаходяться на протилежних кінцях, доповнюючи одна одну.

Requests мають дуже простий та інтуїтивно зрозумілий дизайн, дуже простий у використанні, з розумними параметрами за замовчуванням. Але в той же час він дуже потужний і налаштовується.

Ось чому, як сказано на офіційному сайті:

> Requests є одним із найбільш завантажуваних пакетів Python усіх часів

Використовувати його дуже просто. Наприклад, щоб виконати запит `GET`, ви повинні написати:

```Python
response = requests.get("http://example.com/some/url")
```

Відповідна операція *роуту* API FastAPI може виглядати так:

```Python hl_lines="1"
@app.get("/some/url")
def read_url():
     return {"message": "Hello World"}
```

Зверніть увагу на схожість у `requests.get(...)` і `@app.get(...)`.

/// check | Надихнуло **FastAPI** на

* Майте простий та інтуїтивно зрозумілий API.
 * Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом.
 * Розумні параметри за замовчуванням, але потужні налаштування.

///

### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI /OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a>

Головною функцією, яку я хотів від Django REST Framework, була автоматична API документація.

Потім я виявив, що існує стандарт для документування API з використанням JSON (або YAML, розширення JSON) під назвою Swagger.

І вже був створений веб-інтерфейс користувача для Swagger API. Отже, можливість генерувати документацію Swagger для API дозволить використовувати цей веб-інтерфейс автоматично.

У якийсь момент Swagger було передано Linux Foundation, щоб перейменувати його на OpenAPI.

Тому, коли говорять про версію 2.0, прийнято говорити «Swagger», а про версію 3+ «OpenAPI».

/// check | Надихнуло **FastAPI** на

Прийняти і використовувати відкритий стандарт для специфікацій API замість спеціальної схеми.

 Інтегрувати інструменти інтерфейсу на основі стандартів:

 * <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Інтерфейс Swagger</a>
 * <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>

 Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**).

///

### Фреймворки REST для Flask

Існує кілька фреймворків Flask REST, але, витративши час і роботу на їх дослідження, я виявив, що багато з них припинено або залишено, з кількома постійними проблемами, які зробили їх непридатними.

### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a>

Однією з головних функцій, необхідних для систем API, є "<abbr title="також звана marshalling, conversion">серіалізація</abbr>", яка бере дані з коду (Python) і перетворює їх на щось, що можна надіслати через мережу. Наприклад, перетворення об’єкта, що містить дані з бази даних, на об’єкт JSON. Перетворення об’єктів `datetime` на строки тощо.

Іншою важливою функцією, необхідною для API, є перевірка даних, яка забезпечує дійсність даних за певними параметрами. Наприклад, що деяке поле є `int`, а не деяка випадкова строка. Це особливо корисно для вхідних даних.

Без системи перевірки даних вам довелося б виконувати всі перевірки вручну, у коді.

Marshmallow створено для забезпечення цих функцій. Це чудова бібліотека, і я часто нею користувався раніше.

Але він був створений до того, як існували підказки типу Python. Отже, щоб визначити кожну <abbr title="визначення того, як дані повинні бути сформовані">схему</abbr>, вам потрібно використовувати спеціальні утиліти та класи, надані Marshmallow.

/// check | Надихнуло **FastAPI** на

Використовувати код для автоматичного визначення "схем", які надають типи даних і перевірку.

///

### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a>

Іншою важливою функцією, необхідною для API, є <abbr title="читання та перетворення даних Python">аналіз</abbr> даних із вхідних запитів.

Webargs — це інструмент, створений, щоб забезпечити це поверх кількох фреймворків, включаючи Flask.

Він використовує Marshmallow в основі для перевірки даних. І створений тими ж розробниками.

Це чудовий інструмент, і я також часто використовував його, перш ніж створити **FastAPI**.

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

Webargs був створений тими ж розробниками Marshmallow.

///

/// check | Надихнуло **FastAPI** на

Мати автоматичну перевірку даних вхідного запиту.

///

### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>

Marshmallow і Webargs забезпечують перевірку, аналіз і серіалізацію як плагіни.

Але документація досі відсутня. Потім було створено APISpec.

Це плагін для багатьох фреймворків (також є плагін для Starlette).

Принцип роботи полягає в тому, що ви пишете визначення схеми, використовуючи формат YAML, у docstring кожної функції, що обробляє маршрут.

І він генерує схеми OpenAPI.

Так це працює у Flask, Starlette, Responder тощо.

Але потім ми знову маємо проблему наявності мікросинтаксису всередині Python строки (великий YAML).

Редактор тут нічим не може допомогти. І якщо ми змінимо параметри чи схеми Marshmallow і забудемо також змінити цю строку документа YAML, згенерована схема буде застарілою.

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

APISpec був створений тими ж розробниками Marshmallow.

///

/// check | Надихнуло **FastAPI** на

Підтримувати відкритий стандарт API, OpenAPI.

///

### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a>

Це плагін Flask, який об’єднує Webargs, Marshmallow і APISpec.

Він використовує інформацію з Webargs і Marshmallow для автоматичного створення схем OpenAPI за допомогою APISpec.

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

Це вирішило необхідність писати YAML (інший синтаксис) всередині рядків документів Python.

Ця комбінація Flask, Flask-apispec із Marshmallow і Webargs була моїм улюбленим бекенд-стеком до створення **FastAPI**.

Їі використання призвело до створення кількох генераторів повного стека Flask. Це основний стек, який я (та кілька зовнішніх команд) використовував досі:

* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>

І ці самі генератори повного стеку були основою [**FastAPI** генераторів проектів](project-generation.md){.internal-link target=_blank}.

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

Flask-apispec був створений тими ж розробниками Marshmallow.

///

/// check | Надихнуло **FastAPI** на

Створення схеми OpenAPI автоматично з того самого коду, який визначає серіалізацію та перевірку.

///

### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (та <a href="https://angular.io/ " class="external-link" target="_blank">Angular</a>)

Це навіть не Python, NestJS — це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular.

Це досягає чогось подібного до того, що можна зробити з Flask-apispec.

Він має інтегровану систему впровадження залежностей, натхненну Angular two. Він потребує попередньої реєстрації «injectables» (як і всі інші системи впровадження залежностей, які я знаю), тому це збільшує багатослівність та повторення коду.

Оскільки параметри описані за допомогою типів TypeScript (подібно до підказок типу Python), підтримка редактора досить хороша.

Але оскільки дані TypeScript не зберігаються після компіляції в JavaScript, вони не можуть покладатися на типи для визначення перевірки, серіалізації та документації одночасно. Через це та деякі дизайнерські рішення, щоб отримати перевірку, серіалізацію та автоматичну генерацію схеми, потрібно додати декоратори в багатьох місцях. Таким чином код стає досить багатослівним.

Він не дуже добре обробляє вкладені моделі. Отже, якщо тіло JSON у запиті є об’єктом JSON із внутрішніми полями, які, у свою чергу, є вкладеними об’єктами JSON, його неможливо належним чином задокументувати та перевірити.

/// check | Надихнуло **FastAPI** на

Використовувати типи Python, щоб мати чудову підтримку редактора.

 Мати потужну систему впровадження залежностей. Знайдіть спосіб звести до мінімуму повторення коду.

///

### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a>

Це був один із перших надзвичайно швидких фреймворків Python на основі `asyncio`. Він був дуже схожий на Flask.

/// note | Технічні деталі

Він використовував <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> замість стандартного циклу Python `asyncio`. Ось що зробило його таким швидким.

 Це явно надихнуло Uvicorn і Starlette, які зараз швидші за Sanic у відкритих тестах.

///

/// check | Надихнуло **FastAPI** на

Знайти спосіб отримати божевільну продуктивність.

 Ось чому **FastAPI** базується на Starlette, оскільки це найшвидша доступна структура (перевірена тестами сторонніх розробників).

///

### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>

Falcon — ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug.

Він розроблений таким чином, щоб мати функції, які отримують два параметри, один «запит» і один «відповідь». Потім ви «читаєте» частини запиту та «записуєте» частини у відповідь. Через такий дизайн неможливо оголосити параметри запиту та тіла за допомогою стандартних підказок типу Python як параметри функції.

Таким чином, перевірка даних, серіалізація та документація повинні виконуватися в коді, а не автоматично. Або вони повинні бути реалізовані як фреймворк поверх Falcon, як Hug. Така сама відмінність спостерігається в інших фреймворках, натхненних дизайном Falcon, що мають один об’єкт запиту та один об’єкт відповіді як параметри.

/// check | Надихнуло **FastAPI** на

Знайти способи отримати чудову продуктивність.

 Разом із Hug (оскільки Hug базується на Falcon) надихнув **FastAPI** оголосити параметр `response` у функціях.

 Хоча у FastAPI це необов’язково, і використовується в основному для встановлення заголовків, файлів cookie та альтернативних кодів стану.

///

### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a>

Я відкрив для себе Molten на перших етапах створення **FastAPI**. І він має досить схожі ідеї:

* Базується на підказках типу Python.
* Перевірка та документація цих типів.
* Система впровадження залежностей.

Він не використовує перевірку даних, серіалізацію та бібліотеку документації сторонніх розробників, як Pydantic, він має свою власну. Таким чином, ці визначення типів даних не можна було б використовувати повторно так легко.

Це вимагає трохи більш докладних конфігурацій. І оскільки він заснований на WSGI (замість ASGI), він не призначений для використання високопродуктивних інструментів, таких як Uvicorn, Starlette і Sanic.

Система впровадження залежностей вимагає попередньої реєстрації залежностей, і залежності вирішуються на основі оголошених типів. Отже, неможливо оголосити більше ніж один «компонент», який надає певний тип.

Маршрути оголошуються в одному місці з використанням функцій, оголошених в інших місцях (замість використання декораторів, які можна розмістити безпосередньо поверх функції, яка обробляє кінцеву точку). Це ближче до того, як це робить Django, ніж до Flask (і Starlette). Він розділяє в коді речі, які відносно тісно пов’язані.

/// check | Надихнуло **FastAPI** на

Визначити додаткові перевірки для типів даних, використовуючи значення "за замовчуванням" атрибутів моделі. Це покращує підтримку редактора, а раніше вона була недоступна в Pydantic.

 Це фактично надихнуло оновити частини Pydantic, щоб підтримувати той самий стиль оголошення перевірки (всі ці функції вже доступні в Pydantic).

///

### <a href="https://github.com/hugapi/hug" class="external-link" target="_blank">Hug</a>

Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме.

Він використовував спеціальні типи у своїх оголошеннях замість стандартних типів Python, але це все одно був величезний крок вперед.

Це також був один із перших фреймворків, який генерував спеціальну схему, що оголошувала весь API у JSON.

Він не базувався на таких стандартах, як OpenAPI та JSON Schema. Тому було б непросто інтегрувати його з іншими інструментами, як-от Swagger UI. Але знову ж таки, це була дуже інноваційна ідея.

Він має цікаву незвичайну функцію: використовуючи ту саму структуру, можна створювати API, а також CLI.

Оскільки він заснований на попередньому стандарті для синхронних веб-фреймворків Python (WSGI), він не може працювати з Websockets та іншими речами, хоча він також має високу продуктивність.

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

Hug створив Тімоті Крослі, той самий творець <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a>, чудовий інструмент для автоматичного сортування імпорту у файлах Python.

///

/// check | Надихнуло **FastAPI** на

Hug надихнув частину APIStar і був одним із найбільш перспективних інструментів, поряд із APIStar.

 Hug надихнув **FastAPI** на використання підказок типу Python для оголошення параметрів і автоматичного створення схеми, що визначає API.

 Hug надихнув **FastAPI** оголосити параметр `response` у функціях для встановлення заголовків і файлів cookie.

///

### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0,5)

Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн.

Це була одна з перших реалізацій фреймворку, що використовує підказки типу Python для оголошення параметрів і запитів, яку я коли-небудь бачив (до NestJS і Molten). Я знайшов його більш-менш одночасно з Hug. Але APIStar використовував стандарт OpenAPI.

Він мав автоматичну перевірку даних, серіалізацію даних і генерацію схеми OpenAPI на основі підказок того самого типу в кількох місцях.

Визначення схеми тіла не використовували ті самі підказки типу Python, як Pydantic, воно було трохи схоже на Marshmallow, тому підтримка редактора була б не такою хорошою, але все ж APIStar був найкращим доступним варіантом.

Він мав найкращі показники продуктивності на той час (перевершив лише Starlette).

Спочатку він не мав автоматичного веб-інтерфейсу документації API, але я знав, що можу додати до нього інтерфейс користувача Swagger.

Він мав систему введення залежностей. Він вимагав попередньої реєстрації компонентів, як і інші інструменти, розглянуті вище. Але все одно це була чудова функція.

Я ніколи не міг використовувати його в повноцінному проекті, оскільки він не мав інтеграції безпеки, тому я не міг замінити всі функції, які мав, генераторами повного стеку на основі Flask-apispec. У моїх невиконаних проектах я мав створити запит на вилучення, додавши цю функцію.

Але потім фокус проекту змінився.

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

Тепер APIStar — це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк.

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

APIStar створив Том Крісті. Той самий хлопець, який створив:

 * Django REST Framework
 * Starlette (на якому базується **FastAPI**)
 * Uvicorn (використовується Starlette і **FastAPI**)

///

/// check | Надихнуло **FastAPI** на

Існувати.

 Ідею оголошення кількох речей (перевірки даних, серіалізації та документації) за допомогою тих самих типів Python, які в той же час забезпечували чудову підтримку редактора, я вважав геніальною ідеєю.

 І після тривалого пошуку подібної структури та тестування багатьох різних альтернатив, APIStar став найкращим доступним варіантом.

 Потім APIStar перестав існувати як сервер, і було створено Starlette, який став новою кращою основою для такої системи. Це стало останнім джерелом натхнення для створення **FastAPI**. Я вважаю **FastAPI** «духовним спадкоємцем» APIStar, удосконалюючи та розширюючи функції, систему введення тексту та інші частини на основі досвіду, отриманого від усіх цих попередніх інструментів.

///

## Використовується **FastAPI**

### <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>

Pydantic — це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою схеми JSON) на основі підказок типу Python.

Це робить його надзвичайно інтуїтивним.

Його можна порівняти з Marshmallow. Хоча він швидший за Marshmallow у тестах. Оскільки він базується на тих самих підказках типу Python, підтримка редактора чудова.

/// check | **FastAPI** використовує його для

Виконання перевірки всіх даних, серіалізації даних і автоматичної документацію моделі (на основі схеми JSON).

 Потім **FastAPI** бере ці дані схеми JSON і розміщує їх у OpenAPI, окремо від усіх інших речей, які він робить.

///

### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>

Starlette — це легкий фреймворк/набір інструментів <abbr title="The new standard for build asynchronous Python web">ASGI</abbr>, який ідеально підходить для створення високопродуктивних asyncio сервісів.

Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти.

Він має:

* Серйозно вражаючу продуктивність.
* Підтримку WebSocket.
* Фонові завдання в процесі.
* Події запуску та завершення роботи.
* Тестового клієнта, побудований на HTTPX.
* CORS, GZip, статичні файли, потокові відповіді.
* Підтримку сеансів і файлів cookie.
* 100% покриття тестом.
* 100% анотовану кодову базу.
* Кілька жорстких залежностей.

Starlette наразі є найшвидшим фреймворком Python із перевірених. Перевершує лише Uvicorn, який є не фреймворком, а сервером.

Starlette надає всі основні функції веб-мікрофреймворку.

Але він не забезпечує автоматичної перевірки даних, серіалізації чи документації.

Це одна з головних речей, які **FastAPI** додає зверху, все на основі підказок типу Python (з використанням Pydantic). Це, а також система впровадження залежностей, утиліти безпеки, створення схеми OpenAPI тощо.

/// note | Технічні деталі

ASGI — це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього.

 Тим не менш, він уже використовується як «стандарт» кількома інструментами. Це значно покращує сумісність, оскільки ви можете переключити Uvicorn на будь-який інший сервер ASGI (наприклад, Daphne або Hypercorn), або ви можете додати інструменти, сумісні з ASGI, як-от `python-socketio`.

///

/// check | **FastAPI** використовує його для

Керування всіма основними веб-частинами. Додавання функцій зверху.

 Сам клас `FastAPI` безпосередньо успадковує клас `Starlette`.

 Отже, усе, що ви можете робити зі Starlette, ви можете робити це безпосередньо за допомогою **FastAPI**, оскільки це, по суті, Starlette на стероїдах.

///

### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>

Uvicorn — це блискавичний сервер ASGI, побудований на uvloop і httptools.

Це не веб-фреймворк, а сервер. Наприклад, він не надає інструментів для маршрутизації. Це те, що фреймворк на кшталт Starlette (або **FastAPI**) забезпечить поверх нього.

Це рекомендований сервер для Starlette і **FastAPI**.

/// check | **FastAPI** рекомендує це як

Основний веб-сервер для запуску програм **FastAPI**.

 Ви можете поєднати його з Gunicorn, щоб мати асинхронний багатопроцесний сервер.

 Додаткову інформацію див. у розділі [Розгортання](deployment/index.md){.internal-link target=_blank}.

///

## Орієнтири та швидкість

Щоб зрозуміти, порівняти та побачити різницю між Uvicorn, Starlette і FastAPI, перегляньте розділ про [Бенчмарки](benchmarks.md){.internal-link target=_blank}.
