Text-to-API: перетворюємо опис у готовий REST API

Text-to-API: перетворюємо опис у готовий REST API

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1302
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    714
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1006

Text-to-API: перетворюємо опис у готовий REST API

Розробка API з нуля — процес, де кожна помилка в дизайні або моделях даних виливається в години переписування коду. Ми стикалися з проєктами, де команди витрачали тижні на створення CRUD і документації, а бізнес-логіка залишалася незакритою. Text-to-API вирішує це: ви описуєте систему словами — ми генеруємо готовий код на FastAPI або Express з тестами, Docker і документацією. Наш досвід показує, що time-to-market скорочується в 3–5 разів, а витрати на шаблонний код — до 80%.

"Text-to-API економить до 80% часу на CRUD-операціях" — з досвіду наших проєктів.

Проблеми, які вирішує Text-to-API

Чому AI-генерація швидша?

Ручне написання ендпоїнтів, моделей даних, схем валідації та тестів займає до 70% часу бекенд-розробника. AI бере на себе шаблонну роботу: парсить опис, будує специфікацію OpenAPI, генерує моделі Pydantic, роутери та тести. Залишається лише бізнес-логіка, яка дійсно потребує уваги.

Які проблеми вирішуємо?

  • Дизайн API. Неправильні URL, методи HTTP, статуси відповіді — часта біль. AI дотримується REST-конвенцій: іменники у множині, правильні коди (201 для POST, 204 для DELETE).
  • Моделі та схеми. Узгодження типів полів, обов'язковості, вкладеності. Генератор створює SQLAlchemy моделі та Pydantic схеми з валідаторами.
  • Тестування. Автоматично генеруються pytest-тести для кожного ендпоїнта, що покривають happy path, 404, валідацію вхідних даних. Тестове покриття сягає 70%.

Архітектура генератора та стек

В основі — мовні моделі (Claude, GPT-4) з тонким налаштуванням промптів через LangChain. Специфікація API парситься в Pydantic-моделі, потім генерується код. Використовуємо структурний вивід: модель повертає валідний JSON, який перетворюється на APISpec.

from anthropic import Anthropic from pathlib import Path import json from pydantic import BaseModel from typing import Literal, Optional client = Anthropic() class APIEndpoint(BaseModel): method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"] path: str summary: str request_body: Optional[dict] = None response_schema: dict auth_required: bool = True query_params: list[dict] = [] class APISpec(BaseModel): title: str description: str version: str base_path: str endpoints: list[APIEndpoint] entities: list[dict] class TextToAPIGenerator: def parse_description(self, description: str) -> APISpec: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, system="""Ты — API-архитектор. Парсишь описание системы в структуру REST API. Правила REST: - Существительные в URL (не глаголы): /users, /orders - Правильные HTTP методы: GET=чтение, POST=создание, PUT=полная замена, PATCH=частичное обновление, DELETE=удаление - Вложенность максимум 2 уровня: /users/{id}/orders - Plural для коллекций: /products, /categories - Пагинация: ?page=1&limit=20 - Фильтрация: ?status=active&created_after=2024-01-01""", messages=[{ "role": "user", "content": f"""Разбери описание и верни JSON спецификацию API: {{ "title": "...", "description": "...", "version": "1.0.0", "base_path": "/api/v1", "entities": [ {{"name": "...", "fields": [{{"name": "...", "type": "...", "required": true}}]}} ], "endpoints": [ {{ "method": "GET|POST|PUT|PATCH|DELETE", "path": "/resource/{{id}}", "summary": "...", "auth_required": true, "request_body": {{"field": "type"}}, "response_schema": {{"id": "int", "name": "str"}}, "query_params": [{{"name": "...", "type": "...", "required": false}}] }} ] }} Описание системы: {description}""" }] ) text = response.content[0].text start = text.find("{") end = text.rfind("}") + 1 data = json.loads(text[start:end]) return APISpec(**data) def generate_fastapi_code(self, spec: APISpec) -> dict[str, str]: files = {} files["models.py"] = self._generate_models(spec) files["schemas.py"] = self._generate_schemas(spec) for entity in spec.entities: router_code = self._generate_router(entity, spec) files[f"routers/{entity['name'].lower()}.py"] = router_code files["main.py"] = self._generate_main(spec) for entity in spec.entities: test_code = self._generate_tests(entity, spec) files[f"tests/test_{entity['name'].lower()}.py"] = test_code return files def _generate_models(self, spec: APISpec) -> str: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, messages=[{ "role": "user", "content": f"""Создай SQLAlchemy 2.0 модели для сущностей: Сущности: {json.dumps(spec.entities, ensure_ascii=False, indent=2)} Требования: - Используй DeclarativeBase - Добавь id (Integer PK autoincrement), created_at, updated_at для всех моделей - Используй правильные типы: String(256), Text, Integer, Float, Boolean, DateTime - Добавь __tablename__ - Добавь relationship() для связей между моделями - Добавь __repr__ для дебага Верни только Python код.""" }] ) return response.content[0].text.strip() def _generate_schemas(self, spec: APISpec) -> str: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, messages=[{ "role": "user", "content": f"""Создай Pydantic v2 схемы для валидации: Сущности: {json.dumps(spec.entities, ensure_ascii=False)} Endpoints: {json.dumps([e.dict() for e in spec.endpoints], ensure_ascii=False)} Для каждой сущности создай: - <Entity>Create — для POST (все обязательные поля) - <Entity>Update — для PATCH (все поля Optional) - <Entity>Response — для ответов (включая id, created_at) - <Entity>ListResponse — с пагинацией Добавь field validators где нужно (email формат, позитивные числа, длина строк). Верни только Python код.""" }] ) return response.content[0].text.strip() def _generate_router(self, entity: dict, spec: APISpec) -> str: entity_endpoints = [ e for e in spec.endpoints if entity["name"].lower() in e.path.lower() ] response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, messages=[{ "role": "user", "content": f"""Создай FastAPI роутер для сущности {entity['name']}. Endpoints для реализации: {json.dumps([e.dict() for e in entity_endpoints], ensure_ascii=False, indent=2)} Требования: - Используй APIRouter с prefix и tags - Dependency injection для DB session (AsyncSession) - Dependency injection для авторизации (get_current_user) - Async/await для всех операций - Правильные HTTP статусы: 201 для POST, 204 для DELETE, 404 если не найдено - Пагинация через query params page/limit - Логирование через structlog Верни только Python код.""" }] ) return response.content[0].text.strip() def _generate_main(self, spec: APISpec) -> str: return f"""from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager {chr(10).join(f"from routers.{e['name'].lower()} import router as {e['name'].lower()}_router" for e in spec.entities)} @asynccontextmanager async def lifespan(app: FastAPI): # Startup yield # Shutdown app = FastAPI( title="{spec.title}", description="{spec.description}", version="{spec.version}", lifespan=lifespan, ) app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) {chr(10).join(f'app.include_router({e["name"].lower()}_router, prefix="{spec.base_path}")' for e in spec.entities)} """ def _generate_tests(self, entity: dict, spec: APISpec) -> str: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=2048, messages=[{ "role": "user", "content": f"""Создай pytest тесты для CRUD endpoints сущности {entity['name']}. Используй: - pytest-asyncio для async тестов - httpx.AsyncClient для HTTP запросов - pytest fixtures для setup/teardown - TestDatabase (SQLite in-memory) для изоляции Покрой: создание, чтение списка, чтение одного, обновление, удаление, 404 случаи, валидацию входных данных. Верни только Python код.""" }] ) return response.content[0].text.strip() 

CLI-інтерфейс для швидкого старту

import click import yaml @click.command() @click.argument("description_file", type=click.Path(exists=True)) @click.option("--output-dir", "-o", default="./generated_api") @click.option("--framework", default="fastapi", type=click.Choice(["fastapi", "express"])) def generate_api(description_file: str, output_dir: str, framework: str): description = Path(description_file).read_text() generator = TextToAPIGenerator() click.echo("Parsing description...") spec = generator.parse_description(description) click.echo(f"Found {len(spec.endpoints)} endpoints, {len(spec.entities)} entities") click.echo("Generating code...") files = generator.generate_fastapi_code(spec) output_path = Path(output_dir) output_path.mkdir(parents=True, exist_ok=True) for filename, content in files.items(): file_path = output_path / filename file_path.parent.mkdir(parents=True, exist_ok=True) file_path.write_text(content) click.echo(f" Created: {filename}") _generate_project_files(output_path, spec) click.echo(f"\nAPI generated in {output_dir}") click.echo("Run: cd generated_api && docker-compose up") if __name__ == "__main__": generate_api() 
Приклад опису для генерації
# Система керування задачами Багатокористувацька система для команд. Сутності: - User: email (унікальний), name, role (admin/member), avatar_url - Team: name, description, owner_id - Project: name, description, team_id, status (active/archived) - Task: title, description, project_id, assignee_id, status (todo/in_progress/done), priority (low/medium/high), due_date Функціональність: - Реєстрація та авторизація (JWT) - CRUD для команд, проєктів, задач - Призначення задач учасникам команди - Фільтрація задач за статусом, виконавцем, пріоритетом - Пагінація всіх списків - Soft delete для задач 

Практичний кейс

Клієнт — B2B-стартап, якому потрібно було отримати MVP backend для маркетплейсу послуг за 2 тижні. 8 сутностей, 45+ ендпоїнтів.

Генерація:

  • Опис продукту (2 сторінки) → APISpec за кілька секунд
  • Генерація коду FastAPI (7 файлів + тести) — кілька хвилин
  • Ручне доопрацювання авторизації — 3 дні
  • Інтеграція платіжного шлюзу — 2 дні

Результат: працюючий MVP через 5 днів замість 14. Тестове покриття — 67% (згенеровано автоматично). Скоротили бюджет на розробку в 3 рази.

AI чудово справляється з CRUD, пагінацією, валідацією, структурою проєкту та тестами happy path. Ручного втручання потребують складні бізнес-правила, алгоритми ціноутворення та нетривіальні SQL-запити.

Процес роботи, терміни та результати

Етапи

  1. Аналіз вимог — вивчаємо опис, уточнюємо деталі, фіксуємо специфікацію.
  2. Генерація специфікації — AI парсить опис у APISpec (сутності, ендпоїнти, типи).
  3. Генерація коду — створюємо повний проєкт: моделі, схеми, роутери, тести, Docker.
  4. Тестування — запускаємо тести, виправляємо помилки, додаємо відсутні кейси.
  5. Деплой і документація — готуємо інструкцію, CI/CD (опціонально).

Терміни та вартість

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

  • Прототип (один файл) — від 2 днів
  • Повний проєкт з тестами — від 1 до 2 тижнів
  • Додавання підтримки нового фреймворку — +1 тиждень
  • Інтеграція в CI/CD — 1 тиждень

Вартість розраховується індивідуально. Зв'яжіться з нами для оцінки вашого проєкту.

Що ви отримуєте в результаті

Компонент Деталі
Специфікація OpenAPI 3.0 (YAML/JSON)
Бекенд-код FastAPI/Express з моделями, схемами, роутерами
Тести pytest з покриттям до 70%
Документація README, інструкція по запуску
Інфраструктура Docker Compose, requirements.txt

Порівняння ручної розробки та AI-генерації

Критерій Ручна розробка AI-генерація
Час на CRUD 3-5 днів 2-10 хвилин
Тестове покриття 40-60% до 70%
Ризик помилок в моделях високий низький (дотримується конвенцій)
Документація пишеться окремо генерується автоматично

Типові помилки при AI-генерації API

  • Відсутність авторизації. AI не знає вашу систему ролей — потребує ручного налаштування.
  • Неправильні HTTP статуси. Іноді модель генерує 200 замість 201 для POST — важливо перевірити.
  • Пропущена валідація. Для специфічних бізнес-правил (унікальність email) потрібно додавати кастомні перевірки.
  • Недостатнє тестування. Тести покривають happy path, але граничні випадки залишаються за кадром.

Наші інженери мають сертифікати AWS та досвід в AI-генерації коду більше 5 років. Гарантуємо відповідність найкращим практикам REST та повну документацію. Замовте демо-генерацію API за вашим описом — переконайтеся самі.