Documentation
¶
Overview ¶
Package axon provides a Go toolkit for building AI-powered web services.
It includes HTTP server lifecycle, configuration, database management, health checks, Prometheus metrics, request logging, auth middleware, SPA static file serving, and slug validation.
Index ¶
- Constants
- Variables
- func DecodeJSON[T any](w http.ResponseWriter, r *http.Request) (T, bool)
- func HealthHandler(db *sql.DB) http.HandlerFuncdeprecated
- func IsStatusError(err error, code int) bool
- func ListenAndServe(port string, handler http.Handler, opts ...ServerOption)
- func LoadClientTLSConfig() (*tls.Config, error)
- func LoadConfig(cfg any) error
- func Meta(ctx context.Context, key string) string
- func MetaHeaders(next http.Handler) http.Handler
- func MeterProvider() *sdkmetric.MeterProvider
- func MetricsHandler() http.Handler
- func MustLoadConfig(cfg any)
- func MustOpenDB(dsn, schema string) *sql.DB
- func MustRunMigrations(db *sql.DB, migrationsFS embed.FS)
- func NewServiceMux(db *sql.DB) *http.ServeMuxdeprecated
- func OpenDB(dsn, schema string) (*sql.DB, error)
- func OpenTestDB(t *testing.T, dsn string, migrations embed.FS) *sql.DB
- func RequestLogging(next http.Handler) http.Handler
- func RequestMetrics(next http.Handler) http.Handler
- func RequireAuth(sv SessionValidator, opts ...AuthOption) func(http.Handler) http.Handler
- func RunID(ctx context.Context) string
- func RunMigrations(db *sql.DB, migrationsFS embed.FS) error
- func SPAHandler(files embed.FS, subdir string, opts ...SPAOption) http.Handler
- func StandardMiddleware(handler http.Handler) http.Handlerdeprecated
- func UserID(ctx context.Context) string
- func Username(ctx context.Context) string
- func ValidateSlug(s string) error
- func WrapHandler(handler http.Handler, checks ...HealthCheck) http.Handler
- func WriteError(w http.ResponseWriter, status int, message string)
- func WriteJSON(w http.ResponseWriter, status int, v any)
- type AuthClient
- type AuthClientOption
- type AuthOption
- type HealthCheck
- type InternalClient
- type SPAOption
- type ServerOption
- func WithDrainTimeout(d time.Duration) ServerOption
- func WithHealthCheck(name string, check func() error) ServerOption
- func WithHookTimeout(d time.Duration) ServerOption
- func WithShutdownHook(fn func(context.Context)) ServerOption
- func WithTLSCert(certFile, keyFile string) ServerOption
- func WithTLSConfig(cfg *tls.Config) ServerOption
- type SessionInfo
- type SessionValidator
- type StatusError
- type Validatable
Constants ¶
const ( // UserIDKey is the context key for the authenticated user's ID. UserIDKey contextKey = "user_id" // UsernameKey is the context key for the authenticated user's username. UsernameKey contextKey = "username" // SessionInfoKey is the context key for the full SessionInfo. SessionInfoKey contextKey = "session_info" )
const (
// MetaKey is the context key for X-Axon-* header metadata.
MetaKey contextKey = "axon_meta"
)
Variables ¶
var ( ErrNotFound = errors.New("not found") )
var ValidSlug = regexp.MustCompile(`^[a-z0-9]+(-[a-z0-9]+)*$`)
ValidSlug matches lowercase alphanumeric slugs with hyphens between words. Examples: "my-agent", "chat", "deploy-gate-v2"
Functions ¶
func DecodeJSON ¶
DecodeJSON decodes the request body as JSON into T. The body is limited to 1MB to prevent abuse. If T implements Validatable, validation runs after decoding. On failure, it writes an error response and returns (zero, false). On success, it returns (value, true).
func HealthHandler
deprecated
func HealthHandler(db *sql.DB) http.HandlerFunc
Deprecated: HealthHandler is superseded by WithHealthCheck which registers named health checks with ListenAndServe.
func IsStatusError ¶
IsStatusError checks if err is a StatusError with the given code.
func ListenAndServe ¶
func ListenAndServe(port string, handler http.Handler, opts ...ServerOption)
ListenAndServe starts an HTTP server and blocks until SIGINT or SIGTERM. Performs graceful shutdown: runs shutdown hooks, then drains connections.
func LoadClientTLSConfig ¶
LoadClientTLSConfig loads mTLS client certificates from environment variables CLIENT_CERT, CLIENT_KEY, and CA_CERT.
func LoadConfig ¶ added in v0.4.0
LoadConfig parses environment variables into the provided struct. The struct should use `env` and `envDefault` tags from caarlos0/env.
func Meta ¶
Meta retrieves an X-Axon-* header value from the request context. The key should be lowercase with prefix stripped: "run-id", "trace-id". Returns empty string if not present.
func MetaHeaders ¶
MetaHeaders returns middleware that extracts X-Axon-* headers into the request context. Downstream handlers access values via Meta or RunID.
Header names are normalised to lowercase keys with the prefix stripped: X-Axon-Run-Id → "run-id", X-Axon-Trace-Id → "trace-id".
func MeterProvider ¶ added in v0.5.0
func MeterProvider() *sdkmetric.MeterProvider
MeterProvider returns the global OTel MeterProvider, allowing domain packages to create their own meters and instruments.
func MetricsHandler ¶
MetricsHandler returns the Prometheus metrics HTTP handler. Serves OTel metrics in Prometheus exposition format.
func MustLoadConfig ¶
func MustLoadConfig(cfg any)
MustLoadConfig parses environment variables into the provided struct. Panics on failure.
func MustOpenDB ¶
MustOpenDB opens a PostgreSQL connection, creates the schema if needed, sets the search_path, and pings to verify connectivity. Panics on failure.
func MustRunMigrations ¶
MustRunMigrations runs goose SQL migrations. Panics on failure.
func NewServiceMux
deprecated
func OpenDB ¶
OpenDB opens a PostgreSQL connection, creates the schema if needed, and sets the search_path via the DSN so it applies to all pooled connections.
func OpenTestDB ¶
OpenTestDB creates a unique PostgreSQL schema for test isolation. It opens a connection, runs migrations, and registers cleanup to drop the schema when the test finishes.
func RequestLogging ¶
RequestLogging returns middleware that logs each request with slog.
func RequestMetrics ¶
RequestMetrics returns middleware that records HTTP request metrics using OpenTelemetry instruments exported as Prometheus metrics.
func RequireAuth ¶
func RequireAuth(sv SessionValidator, opts ...AuthOption) func(http.Handler) http.Handler
RequireAuth returns middleware that validates session tokens via a SessionValidator. On success, sets UserIDKey, UsernameKey, and SessionInfoKey in the request context. On failure, responds with 401 or 503.
func RunMigrations ¶
RunMigrations runs goose SQL migrations from an embedded filesystem. The migrations FS should embed a "migrations" directory containing SQL files (e.g., //go:embed migrations/*.sql).
func SPAHandler ¶
SPAHandler serves embedded static files with SPA fallback. Files are served from the given subdirectory of the embed.FS. Unknown routes get index.html (for client-side routing). Use WithStaticPrefix to make paths under a given prefix 404 on miss instead of falling back to index.html. index.html is served with Cache-Control: no-cache.
func StandardMiddleware
deprecated
func UserID ¶
UserID extracts the authenticated user ID from the request context. Returns empty string if not present.
func Username ¶
Username extracts the authenticated username from the request context. Returns empty string if not present.
func ValidateSlug ¶
ValidateSlug returns an error if s is not a valid slug.
func WrapHandler ¶ added in v0.5.0
func WrapHandler(handler http.Handler, checks ...HealthCheck) http.Handler
WrapHandler wraps a user handler with automatic observability:
- GET /metrics — Prometheus metrics endpoint
- GET /health — health check endpoint (extensible via WithHealthCheck)
- All other routes — delegated through StandardMiddleware (logging + metrics)
Routes /metrics and /health are reserved and cannot be overridden by the inner handler.
func WriteError ¶
func WriteError(w http.ResponseWriter, status int, message string)
WriteError writes a JSON error response: {"error": "message"}.
Types ¶
type AuthClient ¶
type AuthClient struct {
// contains filtered or unexported fields
}
AuthClient validates session tokens against a remote auth service.
func NewAuthClient ¶
func NewAuthClient(authServiceURL string, opts ...AuthClientOption) (*AuthClient, error)
NewAuthClient creates an AuthClient with mTLS from environment variables. Returns an error if client TLS configuration fails.
func NewAuthClientPlain ¶
func NewAuthClientPlain(authServiceURL string, opts ...AuthClientOption) *AuthClient
NewAuthClientPlain creates an AuthClient without mTLS (plain HTTP). Use for services that talk to auth over localhost.
func (*AuthClient) Close ¶
func (ac *AuthClient) Close()
Close stops the cache cleanup goroutine. Safe to call multiple times.
func (*AuthClient) ValidateSession ¶
func (ac *AuthClient) ValidateSession(sessionToken string) (*SessionInfo, error)
type AuthClientOption ¶
type AuthClientOption func(*authClientConfig)
AuthClientOption configures AuthClient behavior.
func WithCacheTTL ¶
func WithCacheTTL(d time.Duration) AuthClientOption
WithCacheTTL sets the duration cached sessions remain valid. Defaults to 30 seconds.
func WithDecodeFunc ¶
WithDecodeFunc sets how the validation response is decoded into claims. Defaults to JSON decoding the response body.
func WithEndpointPath ¶
func WithEndpointPath(path string) AuthClientOption
WithEndpointPath sets the validation endpoint path. Defaults to "/api/validate".
func WithTokenSender ¶
func WithTokenSender(fn func(*http.Request, string)) AuthClientOption
WithTokenSender sets how the session token is attached to the validation request. Defaults to sending as a cookie named "session".
type AuthOption ¶
type AuthOption func(*authConfig)
AuthOption configures RequireAuth behavior.
func WithCookieName ¶
func WithCookieName(name string) AuthOption
WithCookieName sets the session cookie name. Defaults to "session".
func WithTokenExtractor ¶
func WithTokenExtractor(fn func(*http.Request) (string, error)) AuthOption
WithTokenExtractor sets a custom function to extract the session token from the request. Overrides the default cookie-based extraction.
type HealthCheck ¶ added in v0.5.0
HealthCheck is a named health check function.
type InternalClient ¶
InternalClient is a lightweight HTTP client for internal service-to-service calls. It handles JSON marshalling/unmarshalling and status code checks.
func NewInternalClient ¶
func NewInternalClient(baseURL string) *InternalClient
NewInternalClient creates a client with sensible defaults (10s timeout).
type SPAOption ¶
type SPAOption func(*spaConfig)
SPAOption configures SPAHandler behavior.
func WithStaticPrefix ¶
WithStaticPrefix sets a URL prefix for static assets that should 404 on miss instead of falling back to index.html. For example, WithStaticPrefix("/_app/") prevents serving HTML for missing JS/CSS. When not set, all unknown paths fall back to index.html.
type ServerOption ¶
type ServerOption func(*serverConfig)
ServerOption configures ListenAndServe behavior.
func WithDrainTimeout ¶
func WithDrainTimeout(d time.Duration) ServerOption
WithDrainTimeout sets the maximum time to wait for in-flight requests to complete during shutdown. Defaults to 30 seconds.
func WithHealthCheck ¶ added in v0.5.0
func WithHealthCheck(name string, check func() error) ServerOption
WithHealthCheck registers a named health check with ListenAndServe. When GET /health is called, all checks run and their results are included in the response. If any check fails, the endpoint returns 503.
func WithHookTimeout ¶
func WithHookTimeout(d time.Duration) ServerOption
WithHookTimeout sets the maximum time to wait for shutdown hooks to complete. Defaults to 10 seconds.
func WithShutdownHook ¶
func WithShutdownHook(fn func(context.Context)) ServerOption
WithShutdownHook registers a function to call before draining connections. Multiple hooks run in registration order. Use for background task cleanup.
func WithTLSCert ¶
func WithTLSCert(certFile, keyFile string) ServerOption
WithTLSCert sets the TLS certificate and key files for ListenAndServeTLS. Must be used together with WithTLSConfig.
func WithTLSConfig ¶
func WithTLSConfig(cfg *tls.Config) ServerOption
WithTLSConfig sets the TLS configuration for the server. Requires WithTLSCert to provide certificate and key files.
type SessionInfo ¶
SessionInfo holds claims from a validated session.
func Session ¶
func Session(ctx context.Context) *SessionInfo
Session extracts the full SessionInfo from the request context. Returns nil if not present.
func (*SessionInfo) Claim ¶
func (s *SessionInfo) Claim(key string) any
Claim returns a single claim value by key, or nil if absent.
func (*SessionInfo) UserID ¶
func (s *SessionInfo) UserID() string
UserID returns the "user_id" claim as a string, or empty if absent.
func (*SessionInfo) Username ¶
func (s *SessionInfo) Username() string
Username returns the "username" claim as a string, or empty if absent.
type SessionValidator ¶
type SessionValidator interface {
ValidateSession(token string) (*SessionInfo, error)
}
SessionValidator validates a session token and returns session info.
type StatusError ¶
type StatusError struct {
Code int
}
StatusError is returned when the server responds with an unexpected HTTP status code.
func (*StatusError) Error ¶
func (e *StatusError) Error() string
type Validatable ¶ added in v0.5.2
type Validatable interface {
Validate() error
}
Validatable is implemented by request types that can validate themselves. DecodeJSON calls Validate automatically after successful decoding.