Skip to content

api: serve the OpenAPI spec and a self-hosted Swagger UI - #58

Merged
vynulldev merged 5 commits into
mainfrom
api-spec
Oct 10, 2026
Merged

vynulldev merged 5 commits into
mainfrom
api-spec

Conversation

@vynulldev

@vynulldev vynulldev commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

What & why

Adds an OpenAPI 3.0 spec for the whole HTTP API, and serves it with a self-hosted Swagger UI.

The API is how the CLI, the web UI, and any external frontend drive a running Vynull, but it was documented only by the handlers themselves. This lands a single docs/api/openapi.yaml (56 paths, 75 operations, 31 schemas) covering every /api/* endpoint, and serves it at /api/openapi.yaml with a browsable Swagger UI at /api/docs (the UI bundle is vendored under docs/api/swagger/ and embedded, so it works offline with no CDN).

The spec is the whole surface in one document, so it also describes the uniform CORS headers and the /api/events SSE stream. The behaviour behind those two lands in #63; documenting them here keeps the spec complete rather than split across files.

This is docs and tooling only: it adds a static spec file, the embedded UI assets, and the routes that serve them. It does not change any existing endpoint's behaviour.

The spec was audited field-by-field against the Go types it documents (every schema's properties checked against the serialized struct's JSON tags); it is drift-free at this commit.

Hardware testing

Pure HTTP API documentation and static-asset serving. Nothing a deck reacts to.

  • Tested on: N/A: no deck-facing change

Checklist

  • go build ./..., go vet ./..., and go test ./... pass
  • gofmt -l . is clean
  • New source files carry an SPDX header (GPL-3.0-or-later)
  • Tested on real hardware (deck + firmware noted above), or this change doesn't affect deck behaviour
  • I agree my contribution is licensed under the project's GPLv3

@vynulldev vynulldev added documentation Improvements or additions to documentation enhancement New feature or request labels Oct 9, 2026
Vynull is a headless daemon and the API is the real contract every client
builds against (the web UI, the overlay, and MPRIS are all just clients).
Document it so a separate frontend, native or otherwise, can be built
against a contract instead of reading the Go handlers.

docs/api/openapi.yaml covers the full surface: ~54 paths / 73 operations
across status/players, the library (tracks, edits, playlists, tags),
playback, analysis (waveforms, cues, beatgrids, artwork), import/export,
settings/menu, overlay, device link, diagnostics, and the file browser.
Schemas are transcribed from the Go response structs. It also states the
posture for frontend authors: no auth (trusted LAN; bind 0.0.0.0 for
cross-device), poll-based live updates (beat_age_ms for playhead
interpolation), partial CORS, and the raw-bytes endpoints (artwork,
waveform-png, preview). Validated: YAML parses, every schema ref resolves.
Add GET|HEAD /api/audio/{trackID} to the OpenAPI spec: serves a library
track's audio by ID with Range/seek support, native formats direct and
others transcoded to WAV, and the X-Audio-Source header. It's the audio
primitive a separate frontend (native app, phone remote) can build on.
Make the HTTP API self-describing. New endpoints, always on (not gated on
--web) so even a headless daemon documents itself:

  GET /api/openapi.yaml   the spec
  GET /api/docs           a browsable Swagger UI
  /api/swagger/*          its assets

Swagger UI is vendored (swagger-ui-dist 5.17.14, Apache-2.0, in
docs/api/swagger/) and embedded, so the docs page pulls nothing from a CDN
and works offline on the link-local network, matching the rest of the UI.
The spec lives in docs/api/ as its canonical home; a small apidocs package
there embeds it and the assets. Adds ~1.6MB to the binary.

Verified live: all four endpoints serve, and the docs page references only
local /api/swagger/ assets (no external calls).
The OverlayConfig struct gained waveform_style, waveform_band, and
waveform_height (the half/full waveform + full-height band work), but the
OpenAPI OverlayConfig schema still documented only the original 11 fields.
Add the three so /api/overlay/config matches the struct.
Document the uniform CORS response headers and the /api/events
Server-Sent-Events stream in the spec. The behaviour they describe lands in
a separate change; the spec carries the whole surface in one document.
@vynulldev vynulldev changed the title api: OpenAPI spec, self-hosted Swagger UI, uniform CORS, and an SSE live-state stream api: add OpenAPI spec and self-hosted Swagger UI Oct 10, 2026
@vynulldev vynulldev changed the title api: add OpenAPI spec and self-hosted Swagger UI api: serve the OpenAPI spec and a self-hosted Swagger UI Oct 10, 2026
@vynulldev
vynulldev marked this pull request as ready for review October 10, 2026 21:11
@vynulldev
vynulldev merged commit e90816d into main Oct 10, 2026
1 check passed
@vynulldev
vynulldev deleted the api-spec branch October 10, 2026 21:19
vynulldev added a commit that referenced this pull request Oct 10, 2026
Two small API changes that let an external frontend drive Vynull: uniform
CORS, and a live event stream. These are the two gaps the frontends direction
has been waiting on, so they go in together.

Uniform CORS: corsMiddleware wraps the whole mux, setting the permissive CORS
headers on every response and answering preflight OPTIONS uniformly. Vynull is
a trusted-LAN tool with no auth and an already-open posture; several handlers
set the same header by hand, so this just makes it consistent everywhere
(preflight included) instead of a per-handler patchwork, so a UI served from
another origin or device can call the API.

SSE stream: GET /api/events is a Server-Sent-Events endpoint that pushes live
deck state as it changes, so a frontend gets push updates instead of polling
/api/players. Self-contained in api/events.go plus one route.

HTTP-side only: a response-header middleware and a new read-only event stream.
Neither touches the Pro DJ Link protocol, the load path, or anything a deck
reacts to. The endpoints are documented in the OpenAPI spec in #58; this
change is code only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant