80 lines
3.6 KiB
Markdown
80 lines
3.6 KiB
Markdown
# OpenAPI snapshot
|
|
|
|
The **machine contract**. The server generates it with NSwag; this folder holds the published snapshot
|
|
so the client can generate or verify types without booting the backend.
|
|
|
|
> Last verified: 2026-07-29 against commit `c99e3f4` (server code last changed in `5885280`, 2026-07-28).
|
|
|
|
| | |
|
|
| --- | --- |
|
|
| File | [`swagger.v1.json`](swagger.v1.json) |
|
|
| Taken | 2026-07-29 |
|
|
| Commit | `c99e3f4` |
|
|
| **Paths** | **178** |
|
|
| **Operations** | **186** |
|
|
| Component schemas | 339 |
|
|
| Generator | NSwag v14.7.1.0 · OpenAPI 3.0.0 |
|
|
| Size | 612 K |
|
|
|
|
## How to regenerate
|
|
|
|
The API binds **plain HTTP** on port 5002 (`launchSettings.json`), despite what most prose in this repo
|
|
says — see contradiction C-3. Use whatever port you bind; the document is the same.
|
|
|
|
```bash
|
|
cd server
|
|
ASPNETCORE_ENVIRONMENT=Development dotnet run \
|
|
--project src/API/Baya.Web.Api/Baya.Web.Api.csproj
|
|
|
|
# from another shell, once "Now listening" appears:
|
|
curl -s --noproxy '*' http://127.0.0.1:5002/swagger/v1/swagger.json \
|
|
-o docs/integration/openapi/swagger.v1.json
|
|
```
|
|
|
|
Two things that cost time the first run:
|
|
|
|
- Booting in `Development` **migrates and seeds** against the DB in `appsettings.Development.json` —
|
|
currently a *remote* SQL Server. First boot takes ~40 s and logs
|
|
`Demo world already seeded — no-op.` when the world is present.
|
|
- `--noproxy '*'` matters. With a proxy configured in the environment, `curl` to `localhost` returns
|
|
**502** rather than the document.
|
|
|
|
Then update the table above — date, commit, and endpoint count — in the same change. A snapshot whose
|
|
provenance is unrecorded is what this chain exists to stop.
|
|
|
|
## Scope — `v1`, and why `v1.1` is empty
|
|
|
|
Both documents **are** registered: `Program.cs` calls `AddSwagger("v1", "v1.1")`, so
|
|
`/swagger/v1.1/swagger.json` is served. It contains **zero paths**.
|
|
|
|
`ApiVersionDocumentProcessor` removes every path whose URL does not contain the document's own version
|
|
segment, and all **55 controllers declare `[ApiVersion("1")]`** with the route template
|
|
`api/v{version:apiVersion}/…`. So every URL contains `v1` and none contains `v1.1`.
|
|
|
|
That resolves contradiction **C-9**: the old README's "publishes `v1` and `v1.1`" was literally true and
|
|
substantively empty. `v1` is the contract. Only `v1` is worth committing.
|
|
|
|
## One provenance wrinkle
|
|
|
|
The document's `servers` block reads `http://127.0.0.1:5099`, while the regeneration command above uses
|
|
port 5002. NSwag records whichever host answered the request, so this only means the phase-0 snapshot was
|
|
taken from a run bound to 5099. **The document content is port-independent** — no path, schema or parameter
|
|
depends on it — so this is a provenance note, not a defect. Re-taking the snapshot from 5002 would change
|
|
that one string and nothing else.
|
|
|
|
## The human contract
|
|
|
|
The prose half — one file per domain — is in [`../domains/`](../domains/index.md): **22 files, one per
|
|
client `services/` domain**, with all 186 operations assigned to exactly one of them. **The two must
|
|
agree**: this JSON is the wire truth, the markdown explains it. When they disagree, the JSON wins and
|
|
the markdown is wrong.
|
|
|
|
Two things the JSON **cannot** tell you, which is why the markdown exists:
|
|
|
|
- **Enum vocabularies.** Exactly 1 of 339 schemas has an `enum`, and it is the integer
|
|
`ApiResultStatusCode`. Every status/code field is a bare `string`. The vocabularies live in the domain
|
|
files, cross-checked against `Baya.Domain`'s code sets.
|
|
- **`Idempotency-Key`.** Two endpoints require it, and neither declares it — it is read from
|
|
`Request.Headers`, not bound as a parameter. See
|
|
[`../api-contract.md`](../api-contract.md#idempotency).
|