food-market/docs/openapi.md
nns dbd08f6fd2 feat(openapi): улучшенный Swagger + TS-клиент через openapi-typescript (P1-19)
API:
• SwaggerGen с OpenAPI info (title/version/description),
  Bearer security-scheme (через OpenIddict JWT),
  стабильные operationId = Controller_VerbAction (HTTP-verb включён
  чтобы избежать коллизии когда ASP.NET стрипает Async-суффикс —
  WipeAll и WipeAllAsync ранее давали одинаковый operationId);
• CustomSchemaIds с префиксом из namespace (одноимённые nested
  record'ы в разных контроллерах больше не схлопываются — StockRow
  есть в Inventory_StockController и Reports_StockReportController).

UI:
• /swagger (UI) и /swagger/v1/swagger.json (документ) — только в Development.
  На prod не раскрываем (endpoint enumeration).

Web:
• Добавлен devDependency openapi-typescript@^7.5.2 + npm-script gen:api,
  читающий http://localhost:5081/swagger/v1/swagger.json.
• src/lib/api.generated.ts — сгенерированные типы (~7700 строк, все
  схемы и operations).
• src/lib/apiClient.ts — тонкая обёртка над axios api, использующая
  типы из generated. Подключена для пары контроллеров (Reports/Sales,
  Reports/ABC, Reports/Profit) как образец постепенной миграции.

docs/openapi.md — workflow генерации (live API или Swashbuckle CLI),
versioning, наставления для нового кода.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 11:39:22 +05:00

2.7 KiB
Raw Permalink Blame History

OpenAPI / Swagger

API публикует OpenAPI-документ через Swashbuckle.AspNetCore. Описание включает security-scheme Bearer (OpenIddict JWT), стабильные operationId = Controller_Action, уникальные schemaId с префиксом из неймспейса (одноимённые nested record'ы в разных контроллерах не схлопываются).

Эндпоинты

URL Когда
/swagger UI, только Development
/swagger/v1/swagger.json JSON-документ, только Development

На stage/prod swagger отключён — отдельный endpoint enumeration не должен раскрываться неавторизованным клиентам. Если нужно — поднимать локальный API из той же ветки.

TypeScript-клиент

В src/food-market.web подключён openapi-typescript (devDependency). Команда:

# Терминал 1: поднять API
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/food-market.api

# Терминал 2: сгенерировать types
cd src/food-market.web
pnpm run gen:api      # читает http://localhost:5081/swagger/v1/swagger.json
                      # → src/lib/api.generated.ts

Альтернативно (без живого API) — через Swashbuckle.AspNetCore.Cli (версия должна совпадать с Swashbuckle.AspNetCore, у нас 6.9.0):

dotnet tool install --global Swashbuckle.AspNetCore.Cli --version 6.9.0
dotnet build src/food-market.api
swagger tofile --output /tmp/swagger.json \
  src/food-market.api/bin/Debug/net8.0/foodmarket.Api.dll v1
cd src/food-market.web
pnpm exec openapi-typescript /tmp/swagger.json -o src/lib/api.generated.ts

Использование

Тонкая обёртка в src/food-market.web/src/lib/apiClient.ts экспортирует типизированные хелперы для отчётов (Reports/Sales, Reports/ABC, Reports/Profit) — образец постепенной миграции с ручных типов в types.ts. В новом коде использовать обёртку и переэкспортированные типы; старые страницы переписывать по мере правок.

Версионирование

Document v1 — единственный. Если будут breaking changes — поднимаем v2 рядом, не ломая v1. У operationId стабильное имя Controller_Action — переименование контроллера ломает TS-клиент, относиться как к public API.