apidoc

package
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package apidoc renders a description of an HTTP surface from the route table that serves it (Task 20257).

cloop exposes two HTTP APIs — the hub dashboard (pkg/ui, 140+ routes) and the standalone REST daemon (pkg/apiserver, 8 routes) — and until this package existed neither had a machine-readable description. An enterprise integrating against a hub read Go source, and the one OpenAPI document that did exist was hand-written beside the mux that it described, with nothing holding the two together.

The fix is not a better hand-written document; it is to stop hand-writing one. A caller hands over its own route table and gets back the OpenAPI document and the Markdown reference for it, so the table stays the single source of truth and a new route appears in both the moment it is registered. What this package cannot do is invent facts the table does not carry: if a route's method or permission is missing from the table, it is missing here too, which is why the callers' drift tests assert the round trip rather than trusting it.

The rendering is deliberately dependency-free — maps and strings, no OpenAPI library — because the document's shape is fixed by the route table and an external schema builder would add a dependency to gain nothing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Markdown

func Markdown(intro string, surfaces []Surface) string

Markdown renders the human-readable endpoint reference.

intro is the page's lead, rendered before the surfaces. The output is deterministic so it can be checked in and gated against the route tables it was generated from.

func OpenAPI

func OpenAPI(info Info, routes []Route) map[string]any

OpenAPI renders an OpenAPI 3.0 document for routes.

The returned value is a plain map so it can be served with the same JSON encoder as every other endpoint, and compared field-by-field in tests without a schema library.

func OperationID

func OperationID(method, path string) string

OperationID derives a stable, unique identifier for an operation.

Exported because the drift tests assert uniqueness across a whole surface: two routes colliding here would silently overwrite one another in any generated client, and that is exactly the failure a generated document is supposed to make impossible.

Types

type Info

type Info struct {
	Title       string
	Version     string
	Description string

	// ServerURL is the base URL advertised in `servers`. Empty omits it,
	// which is correct for a hub that does not know its own external URL.
	ServerURL string

	// BearerAuth and CookieAuth select the security schemes offered.
	BearerAuth bool
	CookieAuth string // cookie name; empty disables the scheme
}

Info is the OpenAPI document's metadata.

type Route

type Route struct {
	// Method is the HTTP verb, upper case ("GET").
	Method string

	// Path is the request path, with ServeMux wildcards left as OpenAPI
	// template parameters — {id} means the same thing in both, which is
	// why no translation is needed.
	Path string

	// Permission is the authorization required, as the wire string the
	// audit trail and /api/me use ("audit.read"). Empty for a surface with
	// no permission model — pkg/apiserver authenticates with a single
	// bearer token and does not distinguish capabilities.
	Permission string

	// Public marks a route reachable before authorization is evaluated.
	// Distinct from an empty Permission: public is a decision, absent is a
	// surface that never makes one.
	Public bool

	// Scope names what the permission is evaluated against ("global",
	// "project", "project-index", "executor"). Empty when not applicable.
	Scope string

	// Summary is a one-line description, shown in both renderings.
	Summary string

	// Subtree marks a ServeMux pattern ending in "/", which matches every
	// path beneath it rather than only itself. Recorded because OpenAPI has
	// no way to express it and a reader would otherwise assume the literal.
	Subtree bool
}

Route is one (method, path) pair a surface serves, together with the access decision it carries.

A Route describes a single OpenAPI operation, so a pattern that serves more than one verb yields one Route per verb. That is what lets the same value describe a method-prefixed pattern and one registered bare: the expansion happens in the caller, which is the only place that knows.

type Surface

type Surface struct {
	// Title names the surface in the Markdown reference.
	Title string

	// Intro is the lead paragraph, rendered as-is (Markdown).
	Intro string

	// Routes is the complete route set, in any order; both renderings sort.
	Routes []Route
}

Surface is one HTTP API: how to describe it, and what it serves.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL