You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

16 KiB

Генерація SDK

Оскільки FastAPI базується на специфікації OpenAPI, його API можна описати у стандартному форматі, який розуміють багато інструментів.

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

У цьому посібнику ви дізнаєтеся, як згенерувати TypeScript SDK для вашого бекенда на FastAPI.

Генератори SDK з відкритим кодом

Універсальним варіантом є OpenAPI Generator, який підтримує багато мов програмування та може генерувати SDK з вашої специфікації OpenAPI.

Для клієнтів TypeScript Hey API — спеціалізоване рішення, що надає оптимізований досвід для екосистеми TypeScript.

Більше генераторів SDK ви можете знайти на OpenAPI.Tools.

/// tip | Порада

FastAPI автоматично генерує специфікації OpenAPI 3.1, тож будь-який інструмент, який ви використовуєте, має підтримувати цю версію.

///

Генератори SDK від спонсорів FastAPI

У цьому розділі представлено рішення від компаній, що спонсорують FastAPI: вони мають венчурну підтримку та корпоративну підтримку. Ці продукти надають додаткові можливості та інтеграції поверх високоякісно згенерованих SDK.

Завдяки спонсорству FastAPI{.internal-link target=_blank} ці компанії допомагають підтримувати фреймворк та його екосистему здоровими та сталими.

Їхня підтримка також демонструє сильну відданість спільноті FastAPI (вам), показуючи, що їм важливо не лише надавати відмінний сервіс, а й підтримувати міцний і процвітаючий фреймворк, FastAPI. 🙇

Наприклад, ви можете спробувати:

Деякі з цих рішень також можуть бути з відкритим кодом або мати безкоштовні тарифи, тож ви можете спробувати їх без фінансових зобов'язань. Інші комерційні генератори SDK також доступні й їх можна знайти онлайн. 🤓

Створити TypeScript SDK

Почнімо з простого застосунку FastAPI:

{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}

Зверніть увагу, що операції шляху визначають моделі, які вони використовують для корисного навантаження запиту та корисного навантаження відповіді, використовуючи моделі Item і ResponseMessage.

Документація API

Якщо ви перейдете до /docs, ви побачите схеми даних, які надсилаються в запитах і приймаються у відповідях:

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

Ця інформація доступна у схемі OpenAPI застосунку, а потім показується в документації API.

Та сама інформація з моделей, яку включено до OpenAPI, може бути використана для генерації клієнтського коду.

Hey API

Коли у нас є застосунок FastAPI з моделями, ми можемо використати Hey API для генерації клієнта TypeScript. Найшвидший спосіб зробити це — через npx.

npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client

Це згенерує TypeScript SDK у ./src/client.

Ви можете дізнатися, як встановити @hey-api/openapi-ts, і почитати про згенерований результат на їхньому сайті.

Використання SDK

Тепер ви можете імпортувати та використовувати клієнтський код. Це може виглядати так; зверніть увагу, що ви отримуєте «автодоповнення» для методів:

Ви також отримаєте автодоповнення для корисного навантаження, яке надсилаєте:

/// tip | Порада

Зверніть увагу на автодоповнення для name і price, які були визначені в застосунку FastAPI, у моделі Item.

///

Ви бачитимете вбудовані помилки для даних, які надсилаєте:

Об'єкт відповіді також матиме автодоповнення:

Застосунок FastAPI з мітками

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

Наприклад, у вас може бути секція для items і окрема секція для users, і їх можна розділити мітками:

{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}

Згенерувати TypeScript-клієнт із мітками

Якщо ви згенеруєте клієнт для застосунку FastAPI, що використовує мітки, зазвичай клієнтський код також буде розділено за цими мітками.

Таким чином, ви матимете правильно впорядковані та згруповані частини клієнтського коду:

У цьому випадку у вас є:

  • ItemsService
  • UsersService

Назви методів клієнта

Зараз згенеровані назви методів на кшталт createItemItemsPost виглядають не дуже охайно:

ItemsService.createItemItemsPost({name: "Plumbus", price: 5})

...це тому, що генератор клієнта використовує внутрішній OpenAPI operation ID для кожної операції шляху.

OpenAPI вимагає, щоб кожен operation ID був унікальним для всіх операцій шляху, тому FastAPI використовує назву функції, шлях і HTTP-метод/операцію для генерації цього operation ID, адже так воно може гарантувати унікальність operation ID.

Але далі я покажу, як це покращити. 🤓

Користувацькі operation ID та кращі назви методів

Ви можете змінити спосіб генерації цих operation ID, щоб зробити їх простішими та мати простіші назви методів у клієнтах.

У цьому випадку вам потрібно буде іншим способом гарантувати, що кожен operation ID є унікальним.

Наприклад, ви можете переконатися, що кожна операція шляху має мітку, а потім генерувати operation ID на основі мітки та назви операції шляху (назви функції).

Користувацька функція генерування унікального ID

FastAPI використовує унікальний ID для кожної операції шляху, який застосовується для operation ID, а також для назв будь-яких потрібних користувацьких моделей для запитів чи відповідей.

Ви можете налаштувати цю функцію. Вона приймає APIRoute і повертає строку.

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

Потім ви можете передати цю користувацьку функцію до FastAPI як параметр generate_unique_id_function:

{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}

Згенерувати TypeScript-клієнт з користувацькими operation ID

Тепер, якщо ви згенеруєте клієнт знову, ви побачите покращені назви методів:

Як бачите, тепер у назвах методів є мітка, а потім назва функції; вони більше не містять інформації з URL-шляху та HTTP-операції.

Попередня обробка специфікації OpenAPI для генератора клієнта

У згенерованому коді все ще є певна дубльована інформація.

Ми вже знаємо, що цей метод стосується items, адже це слово є в ItemsService (взято з мітки), але все ще маємо назву мітки як префікс у назві методу. 😕

Ми, ймовірно, все одно захочемо зберегти це загалом для OpenAPI, адже так гарантується унікальність operation ID.

Але для згенерованого клієнта ми можемо змінити operation ID в OpenAPI безпосередньо перед генерацією клієнтів, просто щоб зробити назви методів приємнішими та чистішими.

Ми можемо завантажити JSON OpenAPI у файл openapi.json, а потім прибрати цей префікс із міткою за допомогою такого скрипту:

{* ../../docs_src/generate_clients/tutorial004_py310.py *}

//// tab | Node.js

{!> ../../docs_src/generate_clients/tutorial004.js!}

////

Після цього operation ID буде перейменовано з чогось на кшталт items-get_items просто на get_items, тож генератор клієнта зможе створити простіші назви методів.

Згенерувати TypeScript-клієнт із попередньо обробленим OpenAPI

Оскільки кінцевий результат тепер у файлі openapi.json, вам потрібно оновити шлях до вхідних даних:

npx @hey-api/openapi-ts -i ./openapi.json -o src/client

Після генерації нового клієнта ви отримаєте чисті назви методів, із усім автодоповненням, вбудованими помилками тощо:

Переваги

Використовуючи автоматично згенеровані клієнти, ви отримаєте автодоповнення для:

  • Методів.
  • Корисного навантаження запиту в тілі, параметрах запиту тощо.
  • Корисного навантаження відповіді.

Також ви матимете вбудовані помилки для всього.

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

Це також означає, що якщо щось змінилося, це буде відображено в клієнтському коді автоматично. А якщо ви зіберете клієнт, буде повідомлено про помилку, якщо є будь-яка невідповідність у використаних даних.

Таким чином, ви виявлятимете багато помилок дуже рано в циклі розробки, замість того, щоб чекати, поки помилки проявляться у ваших кінцевих користувачів у продакшені, і лише потім намагатися з'ясувати, у чому проблема.