# Генерація SDK { #generating-sdks }
Оскільки **FastAPI** базується на специфікації **OpenAPI**, його API можна описати у стандартному форматі, який розуміють багато інструментів.
Це спрощує створення актуальної **документації**, клієнтських бібліотек (**SDKs**) багатьма мовами, а також **тестування** чи **автоматизованих робочих процесів**, що залишаються синхронізованими з вашим кодом.
У цьому посібнику ви дізнаєтеся, як згенерувати **TypeScript SDK** для вашого бекенда на FastAPI.
## Генератори SDK з відкритим кодом { #open-source-sdk-generators }
Універсальним варіантом є [OpenAPI Generator](https://openapi-generator.tech/), який підтримує **багато мов програмування** та може генерувати SDK з вашої специфікації OpenAPI.
Для **клієнтів TypeScript** [Hey API](https://heyapi.dev/) — спеціалізоване рішення, що надає оптимізований досвід для екосистеми TypeScript.
Більше генераторів SDK ви можете знайти на [OpenAPI.Tools](https://openapi.tools/#sdk).
/// tip | Порада
FastAPI автоматично генерує специфікації **OpenAPI 3.1**, тож будь-який інструмент, який ви використовуєте, має підтримувати цю версію.
///
## Генератори SDK від спонсорів FastAPI { #sdk-generators-from-fastapi-sponsors }
У цьому розділі представлено рішення від компаній, що спонсорують FastAPI: вони мають **венчурну підтримку** та **корпоративну підтримку**. Ці продукти надають **додаткові можливості** та **інтеграції** поверх високоякісно згенерованих SDK.
Завдяки ✨ [**спонсорству FastAPI**](../help-fastapi.md#sponsor-the-author) ✨ ці компанії допомагають підтримувати фреймворк та його **екосистему** здоровими та **сталими**.
Їхня підтримка також демонструє сильну відданість **спільноті** FastAPI (вам), показуючи, що їм важливо не лише надавати **відмінний сервіс**, а й підтримувати **міцний і процвітаючий фреймворк**, FastAPI. 🙇
Наприклад, ви можете спробувати:
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
Деякі з цих рішень також можуть бути з відкритим кодом або мати безкоштовні тарифи, тож ви можете спробувати їх без фінансових зобов'язань. Інші комерційні генератори SDK також доступні й їх можна знайти онлайн. 🤓
## Створити TypeScript SDK { #create-a-typescript-sdk }
Почнімо з простого застосунку FastAPI:
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
Зверніть увагу, що *операції шляху* визначають моделі, які вони використовують для корисного навантаження запиту та корисного навантаження відповіді, використовуючи моделі `Item` і `ResponseMessage`.
### Документація API { #api-docs }
Якщо ви перейдете до `/docs`, ви побачите **схеми** даних, які надсилаються в запитах і приймаються у відповідях:
Ви бачите ці схеми, оскільки їх було оголошено як моделі в застосунку.
Ця інформація доступна у **схемі OpenAPI** застосунку, а потім показується в документації API.
Та сама інформація з моделей, яку включено до OpenAPI, може бути використана для **генерації клієнтського коду**.
### Hey API { #hey-api }
Коли у нас є застосунок FastAPI з моделями, ми можемо використати Hey API для генерації клієнта TypeScript. Найшвидший спосіб зробити це — через npx.
```sh
npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
```
Це згенерує TypeScript SDK у `./src/client`.
Ви можете дізнатися, як [встановити `@hey-api/openapi-ts`](https://heyapi.dev/openapi-ts/get-started), і почитати про [згенерований результат](https://heyapi.dev/openapi-ts/output) на їхньому сайті.
### Використання SDK { #using-the-sdk }
Тепер ви можете імпортувати та використовувати клієнтський код. Це може виглядати так; зверніть увагу, що ви отримуєте «автодоповнення» для методів:
Ви також отримаєте автодоповнення для корисного навантаження, яке надсилаєте:
/// tip | Порада
Зверніть увагу на автодоповнення для `name` і `price`, які були визначені в застосунку FastAPI, у моделі `Item`.
///
Ви бачитимете вбудовані помилки для даних, які надсилаєте:
Об'єкт відповіді також матиме автодоповнення:
## Застосунок FastAPI з мітками { #fastapi-app-with-tags }
У багатьох випадках ваш застосунок FastAPI буде більшим, і ви, ймовірно, використовуватимете мітки, щоб розділяти різні групи *операцій шляху*.
Наприклад, у вас може бути секція для **items** і окрема секція для **users**, і їх можна розділити мітками:
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### Згенерувати TypeScript-клієнт із мітками { #generate-a-typescript-client-with-tags }
Якщо ви згенеруєте клієнт для застосунку FastAPI, що використовує мітки, зазвичай клієнтський код також буде розділено за цими мітками.
Таким чином, ви матимете правильно впорядковані та згруповані частини клієнтського коду:
У цьому випадку у вас є:
* `ItemsService`
* `UsersService`
### Назви методів клієнта { #client-method-names }
Зараз згенеровані назви методів на кшталт `createItemItemsPost` виглядають не дуже охайно:
```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```
...це тому, що генератор клієнта використовує внутрішній OpenAPI **operation ID** для кожної *операції шляху*.
OpenAPI вимагає, щоб кожен operation ID був унікальним для всіх *операцій шляху*, тому FastAPI використовує **назву функції**, **шлях** і **HTTP-метод/операцію** для генерації цього operation ID, адже так воно може гарантувати унікальність operation ID.
Але далі я покажу, як це покращити. 🤓
## Користувацькі operation ID та кращі назви методів { #custom-operation-ids-and-better-method-names }
Ви можете **змінити** спосіб **генерації** цих operation ID, щоб зробити їх простішими та мати **простіші назви методів** у клієнтах.
У цьому випадку вам потрібно буде іншим способом гарантувати, що кожен operation ID є **унікальним**.
Наприклад, ви можете переконатися, що кожна *операція шляху* має мітку, а потім генерувати operation ID на основі **мітки** та **назви** *операції шляху* (назви функції).
### Користувацька функція генерування унікального ID { #custom-generate-unique-id-function }
FastAPI використовує **унікальний ID** для кожної *операції шляху*, який застосовується для **operation ID**, а також для назв будь-яких потрібних користувацьких моделей для запитів чи відповідей.
Ви можете налаштувати цю функцію. Вона приймає `APIRoute` і повертає строку.
Наприклад, тут використовується перша мітка (у вас, ймовірно, буде лише одна мітка) і назва *операції шляху* (назва функції).
Потім ви можете передати цю користувацьку функцію до **FastAPI** як параметр `generate_unique_id_function`:
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### Згенерувати TypeScript-клієнт з користувацькими operation ID { #generate-a-typescript-client-with-custom-operation-ids }
Тепер, якщо ви згенеруєте клієнт знову, ви побачите покращені назви методів:
Як бачите, тепер у назвах методів є мітка, а потім назва функції; вони більше не містять інформації з URL-шляху та HTTP-операції.
### Попередня обробка специфікації OpenAPI для генератора клієнта { #preprocess-the-openapi-specification-for-the-client-generator }
У згенерованому коді все ще є певна **дубльована інформація**.
Ми вже знаємо, що цей метод стосується **items**, адже це слово є в `ItemsService` (взято з мітки), але все ще маємо назву мітки як префікс у назві методу. 😕
Ми, ймовірно, все одно захочемо зберегти це загалом для OpenAPI, адже так гарантується унікальність operation ID.
Але для згенерованого клієнта ми можемо **змінити** operation ID в OpenAPI безпосередньо перед генерацією клієнтів, просто щоб зробити назви методів приємнішими та **чистішими**.
Ми можемо завантажити JSON OpenAPI у файл `openapi.json`, а потім **прибрати цей префікс із міткою** за допомогою такого скрипту:
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js
```Javascript
{!> ../../docs_src/generate_clients/tutorial004.js!}
```
////
Після цього operation ID буде перейменовано з чогось на кшталт `items-get_items` просто на `get_items`, тож генератор клієнта зможе створити простіші назви методів.
### Згенерувати TypeScript-клієнт із попередньо обробленим OpenAPI { #generate-a-typescript-client-with-the-preprocessed-openapi }
Оскільки кінцевий результат тепер у файлі `openapi.json`, вам потрібно оновити шлях до вхідних даних:
```sh
npx @hey-api/openapi-ts -i ./openapi.json -o src/client
```
Після генерації нового клієнта ви отримаєте **чисті назви методів**, із усім **автодоповненням**, **вбудованими помилками** тощо:
## Переваги { #benefits }
Використовуючи автоматично згенеровані клієнти, ви отримаєте **автодоповнення** для:
* Методів.
* Корисного навантаження запиту в тілі, параметрах запиту тощо.
* Корисного навантаження відповіді.
Також ви матимете **вбудовані помилки** для всього.
І щоразу, коли ви оновлюєте код бекенда та **перегенеровуєте** фронтенд, у ньому з'являтимуться нові *операції шляху* як методи, старі буде видалено, а будь-які інші зміни відобразяться у згенерованому коді. 🤓
Це також означає, що якщо щось змінилося, це буде **відображено** в клієнтському коді автоматично. А якщо ви **зіберете** клієнт, буде повідомлено про помилку, якщо є будь-яка **невідповідність** у використаних даних.
Таким чином, ви **виявлятимете багато помилок** дуже рано в циклі розробки, замість того, щоб чекати, поки помилки проявляться у ваших кінцевих користувачів у продакшені, і лише потім намагатися з'ясувати, у чому проблема. ✨