# REST API Design с помощью AI: принципы, промпты и OpenAPI-спецификация

> Практическое руководство по проектированию REST API с AI-ассистентом: naming conventions, versioning, error handling, генерация OpenAPI spec. Готовые промпты для каждого этапа.
> Author: Roman Belov · Published: 2026-05-19 · Source: https://futurecraft.pro/ru/blog/rest-api-design-ai/

Плохой API — одна из главных причин срыва сроков на фронтенде. Не баги, не перформанс. Непоследовательные названия эндпоинтов, непредсказуемые ответы на ошибки, отсутствие документации. Один неудачный контракт между бэкендом и фронтендом стоит десятки часов на переделку обеих сторон.

AI меняет процесс проектирования API. Не заменяет архитектора, а ускоряет рутину: генерация OpenAPI-спецификации, проверка naming conventions, моделирование error responses. При правильных промптах LLM выдаёт спецификацию, которую фронтенд-разработчик читает без вопросов.

Дальше разберём полный цикл: от принципов дизайна до готовой OpenAPI-спецификации, сгенерированной с помощью AI. Каждый шаг с конкретным промптом и результатом.

## Принципы REST API Design, которые экономят время

Прежде чем открывать чат с AI, нужно зафиксировать правила. LLM генерирует качественные спецификации только при чётких ограничениях. Без них получается каша из разных стилей именования и несогласованных ответов.

**Ресурсы, а не действия.** URL описывает существительное, HTTP-метод описывает действие. `/users` + `GET` вместо `/getUsers`. `/orders/{id}` + `DELETE` вместо `/deleteOrder`. Правило кажется очевидным, но AI без явного указания часто генерирует RPC-стиль: `/createUser`, `/updateOrder`.

**Множественное число для коллекций.** `/users`, `/products`, `/orders`. Единственное число допустимо только для singleton-ресурсов типа `/users/{id}/profile`.

**Вложенность не глубже двух уровней.** `/users/{userId}/orders` допустимо. `/users/{userId}/orders/{orderId}/items/{itemId}/reviews` избыточно. Глубокая вложенность усложняет клиентский код и создаёт проблемы с кэшированием. Лучше вынести в отдельный ресурс: `/order-items/{itemId}/reviews`.

**Консистентный формат ответов.** Каждый эндпоинт возвращает данные в одинаковой обёртке. Фронтенд-разработчик не должен гадать, придёт `{ data: [...] }` или голый массив. Один формат для успеха, один для ошибки.

**Идемпотентность PUT и DELETE.** Повторный вызов `PUT /users/123` с теми же данными возвращает тот же результат. Повторный `DELETE /users/123` возвращает 204 или 404, но не создаёт побочных эффектов. Это критично для retry-логики на фронтенде и в [circuit breaker паттернах](/ru/blog/circuit-breaker-deno-edge-functions/).

## Naming Conventions: как AI помогает сохранить единообразие

Naming conventions определяют, будет ли API читаемым через полгода. В проекте из 50+ эндпоинтов ручное соблюдение единообразия практически невозможно. Один разработчик пишет `userId`, другой `user_id`, третий `UserID`. Выбор между одним API в монолите и множеством API в сервисах - отдельный вопрос, для которого есть [сравнение монолита и микросервисов](/ru/blog/monolith-vs-microservices/).

AI решает эту задачу через валидацию. Промпт для проверки naming conventions:

```
Проанализируй следующий список эндпоинтов REST API.
Проверь на соответствие правилам:
- URL: kebab-case для составных слов (/order-items, не /orderItems)
- Query parameters: camelCase (pageSize, sortBy)
- Request/Response body: camelCase для JSON-полей
- Path parameters: camelCase ({userId}, не {user_id})
- Коллекции: множественное число
- Вложенность: не глубже 2 уровней

Для каждого нарушения укажи: эндпоинт, правило, текущий вариант, исправленный вариант.

Эндпоинты:
[вставить список]
```

Результат: таблица с конкретными исправлениями.

Для генерации новых эндпоинтов по доменной модели:

```
Дана доменная модель:
- User (id, email, name, role)
- Project (id, title, ownerId, status)
- Task (id, projectId, assigneeId, title, status, priority)

Сгенерируй список REST-эндпоинтов для CRUD-операций.
Правила:
- Базовый путь: /api/v1
- Только необходимые вложенные ресурсы (1 уровень)
- Для каждого эндпоинта укажи: метод, путь, краткое описание, коды ответов

Формат: таблица Markdown.
```

AI генерирует полный набор эндпоинтов за секунды. Дальше остаётся проверить бизнес-логику: нужен ли `PATCH /tasks/{id}/status` как отдельный эндпоинт или достаточно `PATCH /tasks/{id}`.

## Versioning стратегии для REST API

Три подхода к версионированию. Каждый с компромиссами.

**URL-based: `/api/v1/users`**. Самый распространённый. Прост в реализации, прост для фронтенда. Минус: при смене версии меняются все URL. Если API публичный, старые версии придётся поддерживать годами.

**Header-based: `Accept: application/vnd.api.v2+json`**. URL остаётся чистым. Версия передаётся в заголовке. Минус: сложнее тестировать (нельзя просто открыть URL в браузере), сложнее документировать.

**Query parameter: `/api/users?version=2`**. URL остаётся стабильным, версия явная. Минус: загрязняет query parameters, конфликтует с кэшированием по URL.

Промпт для выбора стратегии с учётом контекста проекта:

```
Контекст:
- Внутренний API для мобильного приложения и веб-клиента
- 3 команды-потребителя
- Релиз-цикл: каждые 2 недели
- Планируется публичный API через 6 месяцев

Сравни три стратегии версионирования REST API (URL path, header, query param).
Для каждой: плюсы, минусы, пример.
Дай рекомендацию с обоснованием для описанного контекста.
```

Для большинства проектов URL-based versioning остаётся оптимальным. AI помогает не с выбором (он почти всегда одинаков), а с планированием миграции между версиями и генерацией deprecation headers.

## Error Handling: единый формат ошибок через AI

Ошибки API определяют опыт фронтенд-разработчика больше, чем успешные ответы. Когда что-то ломается, разработчик открывает DevTools и видит ответ. Если там `500 Internal Server Error` без деталей, отладка превращается в детективную историю.

Формат ошибок RFC 9457 (Problem Details for HTTP APIs) решает эту проблему:

```json
{
  "type": "https://api.example.com/errors/validation",
  "title": "Validation Error",
  "status": 422,
  "detail": "Request body contains invalid fields",
  "instance": "/api/v1/users",
  "errors": [
    {
      "field": "email",
      "message": "Must be a valid email address",
      "code": "INVALID_FORMAT"
    },
    {
      "field": "name",
      "message": "Must be between 2 and 100 characters",
      "code": "INVALID_LENGTH"
    }
  ]
}
```

Промпт для генерации полного каталога ошибок:

```
Сгенерируй каталог ошибок для REST API управления проектами.
Домен: Users, Projects, Tasks.

Требования:
- Формат: RFC 9457 (Problem Details)
- Категории: validation, authentication, authorization, not_found, conflict, rate_limit, internal
- Для каждой ошибки: type (URI), title, status code, пример detail, error code (UPPER_SNAKE_CASE)
- Коды ошибок уникальны и машиночитаемы

Формат вывода: таблица с колонками: Category, Error Code, Status, Title, Example Detail.
```

AI генерирует каталог из 20-30 ошибок, покрывающий основные сценарии. После генерации каталог становится контрактом. Фронтенд использует `error.code` для программной обработки (`INVALID_FORMAT` показывает подсказку у поля), `error.detail` — для отладки.

Типичные коды и когда их использовать:

| Status | Когда | Пример |
|--------|-------|--------|
| 400 | Невалидный JSON, отсутствуют обязательные поля | Тело запроса не парсится |
| 401 | Отсутствует или невалидный токен | Expired JWT |
| 403 | Токен валиден, но нет прав | Пользователь не owner проекта |
| 404 | Ресурс не найден | Нет проекта с таким ID |
| 409 | Конфликт состояния | Email уже зарегистрирован |
| 422 | Валидация бизнес-правил | Нельзя удалить проект с активными задачами |
| 429 | Rate limit | Превышен лимит запросов |

Частая ошибка: путать 400 и 422. 400 означает синтаксически невалидный запрос (битый JSON). 422 означает синтаксически валидный, но семантически неверный (email в неправильном формате). Фронтенд обрабатывает их по-разному.

## Генерация OpenAPI-спецификации с помощью AI

OpenAPI (Swagger) спецификация превращает описание API из документа в исполняемый контракт. Фронтенд генерирует типы и API-клиент. Бэкенд валидирует запросы. Тестировщик генерирует тест-кейсы.

Ручное написание OpenAPI YAML для 30+ эндпоинтов занимает часы. AI сокращает это до минут. Ключ в правильном промпте.

### Шаг 1: базовая спецификация

```
Сгенерируй OpenAPI 3.1 спецификацию в YAML для REST API управления задачами.

Ресурсы:
- Users: CRUD, поля (id, email, name, role, createdAt, updatedAt)
- Projects: CRUD + list by user, поля (id, title, description, status, ownerId, createdAt)
- Tasks: CRUD + list by project + update status, поля (id, title, description, status, priority, projectId, assigneeId, createdAt, updatedAt)

Требования:
- Базовый путь: /api/v1
- Аутентификация: Bearer JWT
- Пагинация: cursor-based (query params: limit, cursor)
- Формат ошибок: RFC 9457
- Naming: kebab-case в URL, camelCase в JSON body
- Переиспользуемые схемы в components/schemas
- Примеры для каждого эндпоинта (requestBody + responses)
- Теги для группировки по ресурсам
```

### Шаг 2: итеративное улучшение

После первой генерации спецификация требует доработки. AI хорошо справляется с итеративным улучшением, если указать конкретные проблемы:

```
Улучши сгенерированную OpenAPI-спецификацию:

1. Добавь rate limiting headers в каждый ответ (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)
2. Добавь ETag и If-None-Match для GET-эндпоинтов
3. Добавь Link header для пагинации (RFC 8288)
4. Убедись, что все 4xx/5xx ответы используют единую схему ProblemDetails
5. Добавь discriminator для поля status в Task (open, in_progress, done, cancelled)
```

### Шаг 3: валидация

```
Проверь OpenAPI-спецификацию на:
- Консистентность naming conventions
- Полноту описания ошибок (все эндпоинты должны описывать 400, 401, 403, 500)
- Наличие примеров для всех requestBody и response
- Правильное использование $ref (нет дублирования схем)
- Корректность HTTP-методов (GET не имеет body, DELETE возвращает 204)

Выведи список проблем с номерами строк и предложениями по исправлению.
```

Три шага превращают черновик в production-ready спецификацию. Весь процесс занимает 15-20 минут вместо нескольких часов.

## Pagination, Filtering и Sorting: контракт для фронтенда

Пагинация определяет, насколько удобно фронтенду работать со списками. Два подхода: offset-based и cursor-based.

**Offset-based** (`?page=2&pageSize=20`) прост в реализации. Фронтенд показывает номера страниц. Минус: при добавлении новых записей страницы "сдвигаются". Пользователь на странице 3 видит запись, которую уже видел на странице 2.

**Cursor-based** (`?cursor=eyJpZCI6MTIzfQ&limit=20`) стабилен. Курсор указывает на конкретную запись, а не на позицию. Записи не дублируются при добавлении новых. Минус: нельзя показать "страница 5 из 12". Подходит для бесконечного скролла.

Промпт для генерации query-параметров фильтрации:

```
Для ресурса Tasks со следующими полями:
- status: enum (open, in_progress, done, cancelled)
- priority: enum (low, medium, high, critical)
- assigneeId: UUID
- projectId: UUID
- createdAt: datetime
- updatedAt: datetime

Сгенерируй набор query-параметров для фильтрации и сортировки.
Правила:
- Фильтры: точное совпадение и диапазоны (для дат)
- Множественные значения через запятую: ?status=open,in_progress
- Сортировка: ?sort=createdAt:desc,priority:asc
- Пагинация: cursor-based
- Формат параметров: camelCase

Выведи таблицу: Parameter, Type, Description, Example.
```

Результат: готовый контракт. Фронтенд знает точный формат каждого параметра. Бэкенд знает, что парсить.

## Промпт для полной генерации API-контракта

Финальный промпт объединяет все принципы. Этот промпт используется в начале проекта для генерации первой версии API-контракта. Дальше он итеративно дорабатывается.

```
Роль: Senior API Architect.

Задача: спроектировать REST API для [описание домена].

Входные данные:
- Доменная модель: [список сущностей с полями и связями]
- Потребители: [веб-клиент, мобильное приложение, внешние интеграции]
- Нефункциональные требования: [RPS, latency, авторизация]

Выходной формат: OpenAPI 3.1 YAML.

Архитектурные решения:
- Versioning: URL-based (/api/v1/)
- Auth: Bearer JWT + refresh tokens
- Pagination: cursor-based
- Error format: RFC 9457 (Problem Details)
- Naming: kebab-case URLs, camelCase JSON
- Идемпотентность: Idempotency-Key header для POST

Для каждого эндпоинта обязательно:
1. Summary и description
2. Все query/path/header parameters с описанием
3. RequestBody schema с примером
4. Response schemas для 2xx и всех возможных 4xx/5xx
5. Security requirements
6. Tags для группировки

Дополнительные секции:
- components/schemas для всех моделей (с required полями)
- components/securitySchemes
- components/parameters для переиспользуемых параметров (pagination, sorting)
- components/responses для стандартных ошибок

Стиль: production-ready, готов к codegen (openapi-generator).
```

Этот промпт работает как техническое задание для AI. Чем точнее ограничения, тем меньше итераций потребуется. Подробнее о структурировании контекста для LLM в [руководстве по context engineering](/ru/blog/context-engineering-guide/).

## Валидация API Design: чеклист перед передачей фронтенду

Сгенерированную спецификацию стоит проверить перед тем, как отдавать фронтенд-команде. AI помогает и здесь, но финальное решение принимает человек.

Промпт для design review:

```
Проведи ревью REST API спецификации как Senior Frontend Developer.
Оцени по критериям:

1. Предсказуемость: одинаковые паттерны для одинаковых операций?
2. Самодокументируемость: названия эндпоинтов и полей понятны без описания?
3. Удобство интеграции: можно ли сгенерировать типизированный клиент?
4. Обработка ошибок: достаточно информации для показа пользователю?
5. Пагинация: удобно ли реализовать infinite scroll и table pagination?
6. Фильтрация: покрывает ли основные UI-сценарии?
7. Кэширование: есть ли ETag, Cache-Control?

Для каждого критерия: оценка (OK / Needs improvement), конкретное замечание, пример исправления.
```

Чеклист для ручной проверки:

- Все эндпоинты следуют одному стилю именования
- HTTP-методы соответствуют семантике (GET не меняет состояние)
- Каждый POST возвращает созданный ресурс с `201 Created` и `Location` header
- PUT и PATCH различаются: PUT заменяет ресурс целиком, PATCH обновляет отдельные поля
- DELETE возвращает 204 (без тела) или 200 (с телом удалённого ресурса)
- Все списки поддерживают пагинацию
- Query parameters для фильтрации задокументированы с допустимыми значениями
- Ответы на ошибки включают machine-readable код (не только текст)
- Security scheme применён ко всем эндпоинтам (кроме public)
- Нет circular references в schemas

## Автоматизация: от спецификации к коду

OpenAPI-спецификация, сгенерированная с помощью AI, становится отправной точкой для автоматизации.

**Генерация типов для фронтенда.** `openapi-typescript` читает YAML и создаёт TypeScript-типы. Фронтенд-разработчик получает автокомплит для каждого поля ответа.

```bash
npx openapi-typescript ./openapi.yaml -o ./src/api/types.ts
```

**Генерация API-клиента.** `openapi-fetch` или `orval` создают типизированный клиент с валидацией запросов на этапе компиляции.

**Валидация на бэкенде.** Middleware сверяет входящие запросы и исходящие ответы с OpenAPI-схемой. Любое отклонение от контракта обнаруживается до попадания в продакшен.

**Mock-сервер.** `prism` от Stoplight поднимает mock API из OpenAPI-файла. Фронтенд начинает интеграцию до готовности бэкенда.

```bash
npx @stoplight/prism-cli mock openapi.yaml
```

Одна спецификация генерирует типы, клиент, валидацию и мок-сервер. Разработка фронтенда и бэкенда идёт параллельно без блокировок.

## Итоги: API Design как инженерная дисциплина

REST API design с AI-ассистентом строится на чёткой последовательности:

1. Зафиксировать принципы и naming conventions до начала генерации
2. Сгенерировать базовую OpenAPI-спецификацию через структурированный промпт
3. Итеративно улучшить: error handling, pagination, headers
4. Провалидировать глазами фронтенд-разработчика (или AI в роли фронтендера)
5. Автоматизировать: типы, клиент, mock-сервер из единой спецификации

AI не заменяет знание принципов API design. Он убирает рутину: набор YAML, проверку naming, генерацию примеров. Архитектурные решения (cursor vs offset, URL vs header versioning, формат ошибок) по-прежнему принимает инженер - и их стоит фиксировать как [Architecture Decision Records](/ru/blog/adr-template-ai/), чтобы обоснование переживало смену команды.

Спецификация, сгенерированная по описанному процессу, становится единым источником правды. Тот же паттерн структурированного промптинга работает для [генерации схемы базы данных из PRD](/ru/blog/prd-to-db-schema/) - другой артефакт, та же дисциплина фиксации ограничений до генерации. Фронтенд знает точный формат ответа. Бэкенд знает, что валидировать. Тестировщик знает, что проверять. Один файл вместо десятков сообщений в чате с вопросом "а что вернёт этот эндпоинт".

---

*Нужна помощь с проектированием API? Я помогаю стартапам внедрять AI-решения и строить продукты — [belov.works](https://belov.works).*
