**Language / Язык:** [English](../api-surface.md) | [Русский](api-surface.md)

# Поверхность API

## Путь запроса

1. Middleware назначает или пересылает ID запроса (`REQUEST_ID_HEADER`).
2. FastAPI направляет запрос в роутер vSphere REST (`/api`, `/rest`), роутер
   SOAP (`/sdk`) или (если `ENABLE_PVE_STUB=true`) в опциональный legacy-стаб.
3. `/api/session` (либо `/rest/com/vmware/cis/session`, либо SOAP `Login`)
   определяет принципала и выдаёт `vmware-api-session-id`.
4. Зависимости `require_read` / `require_privilege(...)` проверяют роли
   сессии перед раскрытием или мутацией ресурсов.
5. Глубокий обработчик (базовая логика инвентаря/жизненного цикла/тегов/
   контента/appliance) или DB-backed поверхность стабов выполняется против
   состояния, хранимого в PostgreSQL.
6. Долгие операции (power, clone, relocate, snapshot, деплой OVF) создают
   долговечную CIS-задачу и возвращают `{ "task": "task-…" }`.

## Две REST-поверхности в одном реестре

- **Core (глубокие) обработчики** — ~104 комбинации verb+path в
  [`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py),
  `vm_ext.py`, `inventory_ext.py`, `platform_rest.py`, `tagging_rest.py`,
  `content_rest.py`, `appliance_ext.py`, `nfc_rest.py`, `tasks.py`. Они
  читают и мутируют напрямую seeded-таблицы инвентаря/тегов/контента/
  appliance.
- **DB-backed поверхность стабов** —
  [`app/vsphere/rest/stub_surface.py`](../../app/vsphere/rest/stub_surface.py)
  отвечает на оставшиеся маршруты индекса операций Broadcom Automation API
  (зарегистрированные из `universe.json`) против `vsphere_api_state`. GET
  возвращает живые payload'ы, производные от инвентаря, когда это возможно,
  иначе — seeded-строки; PUT/PATCH сохраняются в `vsphere_api_state`; POST
  добавляет строки коллекции; DELETE их удаляет. Маркер `"stub": true` не
  возвращается — зонды видят реальные seeded-payload'ы.

Обе поверхности используют одну таблицу маршрутов; core-обработчики имеют
приоритет над записями стабов, зарегистрированными для того же verb+path.

## Legacy `/rest`

[`app/vsphere/rest/legacy.py`](../../app/vsphere/rest/legacy.py) оборачивает
чтения vm/host/datastore/network/datacenter/cluster/power/appliance (и
power ВМ) в конверты `{ "value": … }` для более старых клиентов
`com.vmware.vcenter.*`.

## Ошибки ([`app/vsphere/errors.py`](../../app/vsphere/errors.py))

| Статус | `error_type` | Типичная причина |
|---|---|---|
| 400 | `invalid_argument` / `already_exists` | Некорректное тело, дублирующееся имя |
| 401 | `unauthenticated` | Отсутствующая/недействительная/истёкшая сессия |
| 403 | `unauthorized` | У сессии нет требуемой привилегии |
| 404 | `not_found` | Неизвестный параметр MOID/path |
| 409 | (зависит от обработчика) | Недопустимый переход состояния питания, конфликт блокировки |
| 501 | `error` | Достижимо только через fallback опционального legacy-стаба для необъявленных методов |

Все тела ошибок следуют форме vSphere Automation:
`{ "error_type": "...", "messages": [{ "default_message": "...", "id": "...", "args": [] }] }`.

## Задачи

Асинхронная работа (power, clone, snapshot, relocate, деплой OVF, guest
customize) возвращает id задачи. Опрашивайте:

```text
GET /api/cis/tasks/{task}
```

Строки задач фиксируются в `vsphere_tasks`; `progress` равен `100`, как
только `status` становится `SUCCEEDED`/`FAILED`. HTTP 200/201 на запросе
мутации означает «принято», а не «ВМ уже в конечном состоянии». См.
[Задачи](domains/tasks.md).

## Исследование

- Интерактивная документация FastAPI: `/docs`
- Инспектор методов в Web UI: `/` → каталог → метод
- Вспомогательные API UI: `/ui/api/catalog`, `/ui/api/method`,
  `/ui/api/compatibility`
- Реестр покрытия: [`app/vsphere/rest/coverage.py`](../../app/vsphere/rest/coverage.py)
- Матрица уровней пути / каталога: [`app/vsphere/contracts/matrix.py`](../../app/vsphere/contracts/matrix.py)

## Эндпоинты совместимости

| Path | Формат |
|---|---|
| `/ui/api/compatibility?major=N` | JSON |

См. [Совместимость](compatibility.md) и [Покрытие API](api-coverage.md) для
полной разбивки Broadcom-universe в сравнении с реализованным.
