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>
2.7 KiB
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.