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>
60 lines
2.7 KiB
Markdown
60 lines
2.7 KiB
Markdown
# 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).
|
||
Команда:
|
||
|
||
```bash
|
||
# Терминал 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):
|
||
|
||
```bash
|
||
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.
|