server

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package server provides an HTTP API surface for browsing Glazed help sections. It is self-contained and has no dependencies on the CLI or Cobra — it only needs a HelpSystem instance to operate.

The public entry point is NewHandler, which returns an http.Handler that can be mounted anywhere. It routes GET /api/health, GET /api/sections, GET /api/sections/search, and GET /api/sections/:slug internally using a lightweight ServeMux.

Example usage as a standalone server:

srv := &http.Server{Addr: ":8088", Handler: server.NewHandler(deps)}
log.Fatal(srv.ListenAndServe())

Example usage as a sub-router on an existing server:

mux := http.NewServeMux()
mux.Handle("/help/", server.NewHandler(deps))
http.ListenAndServe(":8080", mux)  // serves /help/api/health, etc.

Package server provides an HTTP API surface for browsing Glazed help sections. It is self-contained and has no dependencies on the CLI or Cobra — it only needs a HelpSystem instance to operate.

Index

Constants

View Source
const APIPathPrefix = "/api"

APIPathPrefix is the URL prefix under which the API handler is mounted. All API routes are relative to this prefix. The constant is exported so callers assembling a combined handler can prefix routes correctly.

View Source
const DefaultAddr = ":8088"

DefaultAddr is the TCP address used by the serve command when no --address is supplied.

Variables

This section is empty.

Functions

func MountPrefix

func MountPrefix(prefix string, h http.Handler) http.Handler

MountPrefix adapts a root-mounted handler so it can be exposed under a prefix such as /help or /docs in an existing HTTP server.

Example:

mux := http.NewServeMux()
h := server.NewServeHandler(deps, spa)
mux.Handle("/help/", server.MountPrefix("/help", h))
mux.Handle("/help", server.MountPrefix("/help", h))

func NewCORSHandler

func NewCORSHandler(h http.Handler) http.Handler

NewCORSHandler returns a middleware that appends CORS headers to every response, allowing any origin (matching the design decision for a local dev tool).

For production deployments that need stricter CORS, callers can wrap this with a custom middleware or replace it with a library such as github.com/rs/cors.

func NewHandler

func NewHandler(deps HandlerDeps) http.Handler

NewHandler returns an http.Handler that serves the Glazed help browser API. It panics if deps.Store is nil.

The returned handler already includes CORS headers for all responses. For callers that want to add additional middleware, use the returned http.Handler directly.

func NewMountedHandler

func NewMountedHandler(prefix string, deps HandlerDeps, spaHandler http.Handler) http.Handler

NewMountedHandler builds a root handler and adapts it for mounting under a prefix in an existing HTTP server.

func NewServeHandler

func NewServeHandler(deps HandlerDeps, spaHandler http.Handler) http.Handler

NewServeHandler composes the API handler and optional SPA handler for use at the server root (/). The returned handler already includes CORS because NewHandler applies it internally.

Types

type ErrorResponse

type ErrorResponse struct {
	// Error is a short machine-readable code, e.g. "not_found" or "bad_request".
	Error string `json:"error"`
	// Message is a human-readable description.
	Message string `json:"message"`
}

ErrorResponse is the shape of all error responses (4xx/5xx).

type Handler

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

Handler is an http.Handler that routes all /api/* requests internally. Construct it with NewHandler.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler by delegating to the internal mux.

type HandlerDeps

type HandlerDeps struct {
	Store  *store.Store
	Logger *slog.Logger
}

HandlerDeps holds the dependencies for all HTTP handlers.

type HealthResponse

type HealthResponse struct {
	OK       bool `json:"ok"`
	Sections int  `json:"sections"`
}

HealthResponse is the shape of GET /api/health.

type ListSectionsParams

type ListSectionsParams struct {
	// SectionType filters by the section type (GeneralTopic, Example, Application, Tutorial).
	// Zero value means "all types".
	SectionType string `json:"section_type,omitempty"`
	// Topic filters by topic name (exact match, case-insensitive).
	Topic string `json:"topic,omitempty"`
	// Command filters by command name (exact match).
	Command string `json:"command,omitempty"`
	// Flag filters by flag name (exact match).
	Flag string `json:"flag,omitempty"`
	// Search performs a full-text search over title, subtitle, short description, and content.
	Search string `json:"search,omitempty"`
	// Limit caps the number of results. Zero or negative means "no limit".
	Limit int `json:"limit,omitempty"`
	// Offset skips the first N results for pagination. Zero means start at beginning.
	Offset int `json:"offset,omitempty"`
}

ListSectionsParams describes optional filters for GET /api/sections. All fields are optional; zero values mean "no filter".

type ListSectionsResponse

type ListSectionsResponse struct {
	// Sections is the list of matching sections (summary shape, no content).
	Sections []SectionSummary `json:"sections"`
	// Total is the total number of matching sections (before pagination).
	Total int `json:"total"`
	// Limit reflects the requested limit, or -1 if no limit was applied.
	Limit int `json:"limit"`
	// Offset reflects the requested offset.
	Offset int `json:"offset"`
}

ListSectionsResponse is the shape of GET /api/sections and GET /api/sections/search.

type SectionDetail

type SectionDetail struct {
	ID         int64    `json:"id"`
	Slug       string   `json:"slug"`
	Type       string   `json:"type"`
	Title      string   `json:"title"`
	Short      string   `json:"short"`
	Topics     []string `json:"topics"`
	Flags      []string `json:"flags"`
	Commands   []string `json:"commands"`
	IsTopLevel bool     `json:"isTopLevel"`
	// Content is the full rendered Markdown body.
	Content string `json:"content"`
}

SectionDetail is the full shape returned by GET /api/sections/:slug.

func DetailFromModel

func DetailFromModel(s *model.Section) SectionDetail

DetailFromModel converts a model.Section into a SectionDetail.

type SectionSummary

type SectionSummary struct {
	ID         int64    `json:"id"`
	Slug       string   `json:"slug"`
	Type       string   `json:"type"`
	Title      string   `json:"title"`
	Short      string   `json:"short"`
	Topics     []string `json:"topics"`
	IsTopLevel bool     `json:"isTopLevel"`
}

SectionSummary is the public shape for a section in list/search results. It intentionally omits the full `content` field to keep responses small.

func SummaryFromModel

func SummaryFromModel(s *model.Section) SectionSummary

SummaryFromModel converts a model.Section into a SectionSummary. It is the only place where this conversion is defined.

type ServeCommand

type ServeCommand struct {
	*cmds.CommandDescription
	// contains filtered or unexported fields
}

ServeCommand implements cmds.BareCommand to start the help browser HTTP server.

func NewServeCommand

func NewServeCommand(hs *help.HelpSystem, spaHandler http.Handler) (*ServeCommand, error)

NewServeCommand creates a BareCommand that starts the help browser HTTP server.

func (*ServeCommand) Run

func (sc *ServeCommand) Run(ctx context.Context, parsedValues *values.Values) error

Run starts the HTTP server. Implements cmds.BareCommand.

type ServeSettings

type ServeSettings struct {
	Address string   `glazed:"address"`
	Paths   []string `glazed:"paths"`
}

ServeSettings holds the parsed flag values for the serve command.

Jump to

Keyboard shortcuts

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