api

package
v1.0.0-rc1 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package api serves the controller's HTTP interface.

Per D1 it is designed UI-first: the API comes first, a TUI view second and a web UI third, and it has to already be the shape those need. That is a constraint on the endpoint set rather than a slogan — every screen a UI has is one request, and every action a user can take is one endpoint:

GET  /healthz                                unauthenticated liveness
GET  /api/v1/status                          the controller's own state
GET  /api/v1/applications                    the list view
GET  /api/v1/applications/{app}              the detail view
GET  /api/v1/applications/{app}/diff         the diff view
GET  /api/v1/applications/{app}/history      the history view
POST /api/v1/applications/{app}/sync         the sync button
GET  /api/v1/events                          live updates, so nothing polls

Applications are read-only: they are declared in the app set, which is either mounted at deploy time or committed to git, and changing them means changing that file rather than posting to this API. The paths are nouns so that CRUD can be added later without any of them moving.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Controller

type Controller interface {
	Status() application.ControllerStatus
}

Controller reports the controller's own state, as distinct from the applications'. *appset.Loop implements it.

type Options

type Options struct {
	Authorizer authz.Authorizer
	Log        *slog.Logger
	// Controller reports where the app set came from and whether it is loading.
	// Absent, the status endpoint still answers — with the application count and
	// an empty app-set mode, which is what "no app-set source is wired" looks
	// like. A status endpoint that 404s is a status endpoint a monitor cannot
	// tell from a dead controller.
	Controller Controller
}

Options tune a Server. Every field has a working default.

type Reconciler

type Reconciler interface {
	Views() []application.View
	View(app string) (application.View, bool)
	Diffs(app string) ([]application.ReleaseDiff, error)
	History(ctx context.Context, app string) (application.History, error)
	SyncNow(ctx context.Context, app string) error
}

Reconciler is what the API serves. *reconcile.Reconciler implements it.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the HTTP interface. It is also a notify.Notifier: the event stream is fed by the same seam that feeds the log, which is why notify appends rather than replaces — a companion adding Slack must not silently kill the UI's live updates.

func New

func New(rec Reconciler, o Options) *Server

New returns a Server over rec.

It does not register itself as a notifier. The caller does that, so that the notifier list is not appended to as a side effect of constructing a server — which in a test suite means one stream per test, all still subscribed.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the router.

func (*Server) Notify

func (s *Server) Notify(ctx context.Context, e notifyEvent)

Notify feeds the event stream. It is the notify.Notifier implementation; the caller registers it.

Jump to

Keyboard shortcuts

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