# Генерація 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 } Використовуючи автоматично згенеровані клієнти, ви отримаєте **автодоповнення** для: * Методів. * Корисного навантаження запиту в тілі, параметрах запиту тощо. * Корисного навантаження відповіді. Також ви матимете **вбудовані помилки** для всього. І щоразу, коли ви оновлюєте код бекенда та **перегенеровуєте** фронтенд, у ньому з'являтимуться нові *операції шляху* як методи, старі буде видалено, а будь-які інші зміни відобразяться у згенерованому коді. 🤓 Це також означає, що якщо щось змінилося, це буде **відображено** в клієнтському коді автоматично. А якщо ви **зіберете** клієнт, буде повідомлено про помилку, якщо є будь-яка **невідповідність** у використаних даних. Таким чином, ви **виявлятимете багато помилок** дуже рано в циклі розробки, замість того, щоб чекати, поки помилки проявляться у ваших кінцевих користувачів у продакшені, і лише потім намагатися з'ясувати, у чому проблема. ✨