Help us shape the future of Go! Take the 2026 Go Developer Survey

api

package
v0.42.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 41 Imported by: 0

Documentation

Overview

Package api exposes Brevis's HTTP interface.

It uses plain net/http. ServeMux's method-and-path routing (Go 1.22+) covers what is needed, and the rule is to avoid a framework when the stdlib does the job. This system's hard work is in the queue, in the scheduler and in the state machine — not in the HTTP.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CachedInFlight

func CachedInFlight(read func(context.Context) (int, error), ttl time.Duration, now func() time.Time) func(context.Context) (int, error)

CachedInFlight keeps read's answer for ttl, as CachedFailing does for the failing list: the badge is drawn on every page and polled by every open tab, and a count a few seconds old says the same thing.

An error is not kept: the next page asks again.

Types

type Actions

type Actions interface {
	// Toggle pauses or resumes; actor is who pressed it, for the events feed.
	Toggle(ctx context.Context, slug, actor string) (bool, error)
	// Disparar runs a workflow now; with a slot, that past slot of its
	// schedule.
	Disparar(ctx context.Context, slug string, now time.Time, params map[string]string, slot *time.Time) (uuid.UUID, error)
	// Cancel stops a run, or asks the dispatcher holding it to; actor is who
	// pressed it.
	Cancel(ctx context.Context, id uuid.UUID, actor string) (postgres.CancelResult, error)
}

Actions are the three effects the screen triggers. A small interface on purpose: the UI must not be able to do anything more to the system than pause a schedule, ask for a run now, and stop one.

type AlertsReader

type AlertsReader interface {
	ForRun(ctx context.Context, runID uuid.UUID) ([]alerts.Record, error)
}

AlertsReader lists a run's alerts. It is a CONSTRUCTOR argument and not a settable field, so that forgetting to wire it is a compile error rather than a screen that quietly stops showing alerts. Two features shipped switched off in one week because nothing outside a test ever set the field they needed.

nil is still allowed, for a process that renders no pages.

type CatalogReader

type CatalogReader interface {
	Catalog(ctx context.Context) ([]postgres.CatalogEntry, error)
	CatalogTarget(ctx context.Context, target string) (*postgres.TargetDetail, error)
	StreamConfigs(ctx context.Context) (map[postgres.StreamKey]*postgres.WriterConfig, error)
	StepConfigs(ctx context.Context) (map[postgres.StepKey]*postgres.WriterConfig, error)
}

CatalogReader lists the destinations the ecosystem writes, for /data. A constructor argument for AlertsReader's reason: forgetting to wire it is a compile error, not a catalog that quietly shows nothing. nil is allowed for a process that renders no pages.

type Checker

type Checker interface {
	Check(ctx context.Context) error
}

Checker is a dependency readiness consults. A small interface on purpose (rule 5): postgres.Pool already satisfies it with no adapter.

type Definitions

type Definitions interface {
	Definition(ctx context.Context, slug string) (wf.Workflow, error)
	// Definitions is every published definition by slug, in one read: what
	// a page with many workflows uses for their logos.
	Definitions(ctx context.Context) (map[string]wf.Workflow, error)
}

Definitions reads a workflow's published definition. Kept apart from `Leitura` because it returns the domain, not a screen projection.

type EndpointCaller

type EndpointCaller interface {
	Configured(api string) bool
	Call(ctx context.Context, api, path string, params url.Values) (endpointcall.Answer, error)
}

EndpointCaller runs a published endpoint for Try it.

type EndpointsReader

type EndpointsReader interface {
	List(ctx context.Context) ([]postgres.PublishedEndpoint, error)
	Get(ctx context.Context, api, name string) (postgres.PublishedEndpoint, bool, error)
	Reading(ctx context.Context, target string) ([]postgres.PublishedEndpoint, error)
}

WithPreview points the console at a SQL service, and says whether this console has a login.

A SETTER AND NOT AN ARGUMENT, because NewUI already takes eight: this one is optional in a way the others are not -- a console with no SQL service is a console that works, and every caller would otherwise pass nil.

THE CREDENTIAL ITSELF AND NOT A BOOLEAN, so that nobody can answer this question wrongly by writing `true`. The only way to get the tabs is to hand over the console's real credential and have it be one; a bool would make "we are protected" something a caller could simply assert.

An ARGUMENT and not a second setter, so forgetting it is a compile error rather than an open console with a warehouse on it. EndpointsReader is what Data → Endpoints reads: what each brevis-sql-api was published with. Never its traffic, which is on the API's /metrics.

type EventsReader

type EventsReader interface {
	RecentEvents(ctx context.Context, q postgres.EventQuery) ([]postgres.Event, string, error)
}

EventsReader reads the event log: what the installation did, newest first.

type FailingReader

type FailingReader interface {
	FailingWorkflows(ctx context.Context) ([]postgres.FailingWorkflow, error)
	// FailureStreak is how many times in a row a workflow failed, for the
	// open run's "why it failed".
	FailureStreak(ctx context.Context, slug string) (int, error)
}

FailingReader is the workflows whose last finished run failed.

func CachedFailing

func CachedFailing(r FailingReader, ttl time.Duration, now func() time.Time) FailingReader

CachedFailing keeps r's answer for ttl. The badge is drawn on every page, and the list costs ~6 ms with a thousand workflows and fifty thousand runs (measured for run-diagnosis); a count that is fifteen seconds old says the same thing to whoever reads it.

An error is not kept: the next page asks again.

type Leitura

type Leitura interface {
	Indicators(ctx context.Context, window time.Duration) (postgres.Indicators, error)
	IndicatorsFor(ctx context.Context, window time.Duration, workflow string) (postgres.Indicators, error)
	RunsPerDay(ctx context.Context, workflow string, days int) ([]postgres.Day, error)
	LoadTrend(ctx context.Context, workflow string, days int) ([]postgres.LoadDay, error)
	RunsPer(ctx context.Context, g postgres.Grain, n int) ([]postgres.Bucket, error)
	InFlight(ctx context.Context, limite int) ([]postgres.RunSummary, error)
	LatestRuns(ctx context.Context, limite int) ([]postgres.RunSummary, error)
	Runs(ctx context.Context, f postgres.RunFilter) ([]postgres.RunSummary, error)
	CountRuns(ctx context.Context, f postgres.RunFilter) (int, error)
	CountRunsByState(ctx context.Context, f postgres.RunFilter) (map[string]int, error)
	// CountRunsInFlight is the sidebar badge's number; it must stay cheap.
	CountRunsInFlight(ctx context.Context) (int, error)
	// WorkflowHistory is a workflow's runs with their params, newest first;
	// with a day, that UTC day's.
	WorkflowHistory(ctx context.Context, slug string, day *time.Time, limit int) ([]postgres.RunSummary, error)
	Workflows(ctx context.Context) ([]postgres.WorkflowSummary, error)
	// Connects is the schemes each workflow's runs wrote since a moment.
	Connects(ctx context.Context, since time.Time) (map[string][]string, error)
	// LastStepRuns is how each step of a workflow went the last time it ran;
	// StepConnects what each step wrote since a moment.
	LastStepRuns(ctx context.Context, slug string) (map[string]postgres.StepRun, error)
	StepConnects(ctx context.Context, slug string, since time.Time) (map[string][]string, error)
	RecentStates(ctx context.Context, slugs []string, n int) (map[string][]postgres.RecentRun, error)
	Schedules(ctx context.Context) ([]postgres.ScheduleSummary, error)
	Projects(ctx context.Context) ([]postgres.ProjectSummary, error)
	QueueDepth(ctx context.Context) (int, int, error)
}

Leitura is what the UI needs from the database. The interface is declared here, in the consumer.

type RunsChart

type RunsChart interface {
	Get(ctx context.Context, id uuid.UUID) (run.Run, error)
	NodeStates(ctx context.Context, id uuid.UUID) (map[string]postgres.NodeState, error)
	LogsDaRun(ctx context.Context, id uuid.UUID) ([]postgres.StepLog, error)
	// WaitingOn says what concurrency limit holds a queued run, if one does.
	WaitingOn(ctx context.Context, id uuid.UUID) (*postgres.Wait, error)
}

RunsChart reads a Run and the state of its steps.

type Server

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

Server carries the router and the dependencies readiness consults.

func NewServer

func NewServer(log *slog.Logger, checkers map[string]Checker, ui *UI) *Server

NewServer builds the router. The checkers are named so that /ready says WHICH dependency failed, and not merely that something did.

`ui` may be nil: a process that only serves health checks does not need the pages, and requiring them would couple the server to the database for no reason.

func NewServerAutenticado

func NewServerAutenticado(log *slog.Logger, checkers map[string]Checker, ui *UI,
	cred auth.Credential, inseguro bool,
) *Server

NewServerAutenticado is the same, requiring a session when the credential is configured. `inseguro` sends the cookie without the Secure flag — needed only for plain http in development, because a Secure cookie never comes back over http and the login would look simply broken.

func (*Server) HTTPServer

func (s *Server) HTTPServer(addr string) *http.Server

HTTPServer returns the configured server. The timeouts exist because net/http's default is none: without them, a slow connection holds a handler indefinitely.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP makes Server an http.Handler, with an access log.

type UI

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

UI registers the server-rendered pages and the JSON the React island consumes.

func NewUI

func (*UI) Registrar

func (u *UI) Registrar(mux *http.ServeMux)

Registrar wires the routes into the mux.

func (*UI) RegistrarLogin

func (u *UI) RegistrarLogin(mux *http.ServeMux, gate *auth.Gate)

RegistrarLogin wires the session routes. It is kept apart from Registrar because it only exists when there is a credential: without one, a login screen that always accepts would be worse than none.

func (*UI) WithEndpointCalls

func (u *UI) WithEndpointCalls(c EndpointCaller, console auth.Credential) *UI

WithEndpointCalls turns on Try it, for the APIs the caller has an address for, AND ONLY ON A CONSOLE THAT ASKS WHO YOU ARE: the console's key is one tenant's for every login, and an open console would hand that tenant's rows to whoever found the address -- the SQL tabs' rule, for their reason.

func (*UI) WithEndpoints

func (u *UI) WithEndpoints(r EndpointsReader) *UI

WithEndpoints turns on Data → Endpoints and the "Read by" of a model's page.

func (*UI) WithEvents

func (u *UI) WithEvents(r EventsReader) *UI

WithEvents turns on the Overview's event log. Without it the tab is empty.

func (*UI) WithFailing

func (u *UI) WithFailing(r FailingReader) *UI

WithFailing turns on the list of failing workflows.

func (*UI) WithGallery

func (u *UI) WithGallery(on bool) *UI

WithGallery serves /_components: every component the screens are built from, with sample data, in one page. For somebody building the console -- the caller turns it on with BREVIS_ENV=local and nowhere else. Off, the route is not registered at all, so it is a 404 rather than a page that explains itself.

func (*UI) WithPreview

func (u *UI) WithPreview(c *sqlserve.Client, console auth.Credential) *UI

func (*UI) WithVersion

func (u *UI) WithVersion(current string, src UpdateSource) *UI

WithVersion shows the running version in the account menu and, when src knows a newer release, an update icon and a notice. A nil src is the version alone.

type UpdateSource

type UpdateSource interface {
	Latest() (r updates.Release, newer, ok bool)
}

UpdateSource knows the newest Brevis released and whether it is newer than the one running.

Jump to

Keyboard shortcuts

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