framework

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 43 Imported by: 0

Documentation

Overview

Package framework provides Gombit's runtime application lifecycle and HTTP surfaces (Gin router escape hatch and Huma contract API).

Index

Constants

View Source
const (
	JobMetadataRequestID = "gombit.request_id"
	JobMetadataTraceID   = "gombit.trace_id"
)

Envelope metadata keys JobPropagator writes.

View Source
const RequestIDHeader = "X-Request-Id"

RequestIDHeader is the HTTP header carrying a stable per-request ID.

View Source
const TraceIDHeader = "X-Trace-Id"

TraceIDHeader exposes the active trace ID for logs, diagnostics, and tests.

View Source
const TraceparentHeader = "Traceparent"

TraceparentHeader is the W3C trace context header.

View Source
const WorkerCommand = "worker"

WorkerCommand is the first argument that makes Run start a jobs worker instead of the HTTP server: `./server worker --queue mail --concurrency 8`. One binary deploys as both the web and the worker process.

Variables

This section is empty.

Functions

func GetRequestID

func GetRequestID(c *gin.Context) string

GetRequestID returns the request ID for the current request. It reads the value requestContextMiddleware propagated through the request context, so it agrees with GetRequestIDFromContext by construction.

func GetRequestIDFromContext

func GetRequestIDFromContext(ctx context.Context) string

GetRequestIDFromContext reads the request ID from a request context.

func GetTraceID

func GetTraceID(c *gin.Context) string

GetTraceID returns the trace ID for the current request. It reads the value requestContextMiddleware propagated through the request context, so it agrees with GetTraceIDFromContext by construction.

func GetTraceIDFromContext

func GetTraceIDFromContext(ctx context.Context) string

GetTraceIDFromContext reads the trace ID from a request context.

func JobPropagator added in v0.5.0

func JobPropagator() jobs.Propagator

JobPropagator carries the request and trace IDs of the request that dispatched a job into the job handler's context, so GetRequestIDFromContext / GetTraceIDFromContext (and the logs that use them) correlate a job with the request that queued it.

func Run

func Run(app *App) error

Run runs app until an interrupt or terminate signal is received: the HTTP server, or, when the process's first argument is "worker", the jobs worker (see RunWorker; `./server worker --help` lists its flags). Other arguments are ignored, as before.

func RunContext

func RunContext(ctx context.Context, app *App) error

RunContext runs app until ctx is canceled or the HTTP server fails.

func RunWorker added in v0.5.0

func RunWorker(ctx context.Context, app *App, opts jobs.WorkerOptions) error

RunWorker runs app as a jobs worker until ctx is canceled: the start hooks, a jobs.Worker over App.Jobs(), then the stop hooks. It serves no HTTP. opts.Queues defaults to the dispatcher's default queue and opts.Logger to the app's logger.

func SanitizeHTML added in v0.2.0

func SanitizeHTML(s string) string

SanitizeHTML strips HTML tags from s and discards the content of dangerous elements (script, style, iframe, object, embed, noscript, textarea), returning plain text. It is the per-value function the optional input sanitizer applies, exported (issue #271 / PERF-13) so an app can strip a specific field from a handler without re-enabling ingress sanitization for the whole request pipeline (Security.SanitizeInput).

A string with no HTML tag is returned unchanged, and so is one that holds a bare "<"/">" without forming a complete tag ("a<b") — see the stripHTML doc for the #118 comparison-text handling. Sanitization is an output-encoding backstop, not a substitute for escaping on output.

func WorkerKillAfter added in v0.5.0

func WorkerKillAfter(args []string) time.Duration

WorkerKillAfter is how long a process supervisor should wait after asking a worker started with args to stop before killing it: its shutdown timeout plus workerShutdownGrace (28s).

Types

type App

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

App owns Gombit's runtime lifecycle and HTTP router.

func New

func New(options ...Option) (*App, error)

New creates an application using process configuration and the default router.

func (*App) API

func (a *App) API() huma.API

API returns the Huma API used for contract-typed route registration.

func (*App) Addr

func (a *App) Addr() string

Addr returns the bound HTTP address after the app has started.

func (*App) Cache

func (a *App) Cache() cache.Cache

func (*App) Config

func (a *App) Config() config.Config

Config returns the typed app configuration.

func (*App) DB

func (a *App) DB() *gorm.DB

DB returns the underlying GORM database escape hatch.

func (*App) Database

func (a *App) Database() *database.DB

Database returns the opened database handle with driver metadata.

func (*App) JobMetrics added in v0.5.0

func (a *App) JobMetrics() *jobs.Metrics

JobMetrics returns the metrics workers in this process record into.

func (*App) Jobs added in v0.5.0

func (a *App) Jobs() *jobs.Dispatcher

Cache returns the configured cache implementation. Jobs returns the job dispatcher: register jobs on Jobs().Registry() at startup, and dispatch with Jobs().Dispatch. The driver comes from Config.Jobs (GOMBIT_JOBS_DRIVER, sync by default), and the registry carries request and trace IDs into job handlers (JobPropagator).

func (*App) Logger

func (a *App) Logger() *zap.Logger

Logger returns the app's Zap logger.

func (*App) OnStart

func (a *App) OnStart(hook Hook)

OnStart registers a start hook. Hooks run in registration order.

func (*App) OnStop

func (a *App) OnStop(hook Hook)

OnStop registers a stop hook. Hooks run in reverse registration order.

func (*App) Redis

func (a *App) Redis() *redis.Client

Redis returns the underlying go-redis client when Redis is enabled.

func (*App) Router

func (a *App) Router() *gin.Engine

Router returns the underlying Gin router escape hatch.

func (*App) Tx added in v0.1.7

func (a *App) Tx(ctx context.Context, fn func(tx *gorm.DB) error) error

Tx runs fn inside a single database transaction: it commits when fn returns nil and rolls back on any error or panic. It is the framework home for transactional multi-model writes (atomically update A + B + C) and for cross-row invariants that must read and write consistently. Model Validate hooks (database.Validator) run inside this transaction too. Use struct writes (Create/Save/Updates(struct)) so Validate sees the values being written — an invariant checked in Validate then cannot commit alongside a change that violates it.

err := app.Tx(ctx, func(tx *gorm.DB) error {
    if err := tx.Create(&a).Error; err != nil { return err }
    b.Count++
    return tx.Save(&b).Error
})

type Hook

type Hook func(context.Context) error

Hook is an application lifecycle callback.

type Option

type Option func(*App) error

Option configures an App.

func WithCSRFExemptPaths added in v0.1.6

func WithCSRFExemptPaths(paths ...string) Option

WithCSRFExemptPaths marks exact request paths that opt out of cookie-mode CSRF enforcement on unsafe methods. Use it for non-browser endpoints that cannot participate in the double-submit defense — webhooks, server-to-server callbacks — which must authenticate themselves by other means (e.g. HMAC signature verification). Paths match the request path exactly, including the API prefix, e.g. "/api/v1/webhooks/github". No effect in JWT mode or when a custom router is supplied via WithRouter.

func WithCache

func WithCache(c cache.Cache) Option

WithCache attaches a cache implementation the caller opened. Unlike the cache App opens for itself via cache.Open (closed automatically on shutdown), App does not call Close on a cache attached this way — the caller keeps ownership and is responsible for closing it, including stopping a cache.Memory janitor goroutine started with cache.WithJanitor.

func WithConfig

func WithConfig(cfg config.Config) Option

WithConfig sets the app configuration. DocsEnabled is taken as given: Default() leaves /docs on even if you later set Environment to production. Use config.DefaultFor(env) or set API.DocsEnabled yourself.

func WithDatabase

func WithDatabase(db *database.DB) Option

WithDatabase attaches an opened database handle to the app.

func WithEmbeddedFrontend

func WithEmbeddedFrontend(fsys fs.FS) Option

WithEmbeddedFrontend stores fsys and, when it contains index.html at its root, installs a Gin NoRoute handler after framework routes so unmatched GET paths serve the SPA. Huma /api/*, /openapi.json, /docs, and the probe routes still win because they are registered before NoRoute runs.

If fsys has no index.html (the gombit new placeholder embed), NoRoute is not installed and unknown paths keep their current 404. Split deploy is the default (C5); embedding is opt-in via gombit build --embed.

func WithJobs added in v0.5.0

func WithJobs(dispatcher *jobs.Dispatcher) Option

WithJobs attaches a job dispatcher the caller opened, instead of the one App opens from Config.Jobs. App does not close a dispatcher attached this way.

func WithLogger

func WithLogger(logger *zap.Logger) Option

WithLogger attaches a Zap logger to the app.

func WithRawBodyPaths added in v0.1.7

func WithRawBodyPaths(paths ...string) Option

WithRawBodyPaths marks exact request paths whose request body must reach the handler byte-for-byte unmodified — webhooks and other server-to-server endpoints that verify a signature over the raw body (e.g. GitHub's X-Hub-Signature-256 HMAC). The XSS input sanitizer, which otherwise re-encodes JSON request bodies, is skipped for these paths.

Such an endpoint also cannot participate in the cookie CSRF double-submit, so raw-body paths are additionally CSRF-exempt (the union with WithCSRFExemptPaths) — declaring a webhook path here is enough. The handler must authenticate the caller itself. Paths match the request path exactly, including the API prefix, e.g. "/api/v1/webhooks/github". No effect when a custom router is supplied via WithRouter.

func WithRedis

func WithRedis(client *redis.Client) Option

WithRedis attaches an application-owned Redis client as the app cache.

func WithRouter

func WithRouter(router *gin.Engine) Option

WithRouter sets the app router.

func WithShutdownDrainDelay added in v0.1.13

func WithShutdownDrainDelay(delay time.Duration) Option

WithShutdownDrainDelay sets a delay between the start of graceful shutdown — when /readyz begins returning 503 (HOST-2 / ADR-015) — and the moment the HTTP listener stops accepting connections. During the delay the server keeps serving, so a host that gates traffic on /readyz observes the 503 and deregisters the instance before any request is connection-refused. Without a delay (the default, 0) the flag still sheds in-flight and keep-alive pollers during the shutdown grace period, but a host opening a fresh probe connection after shutdown begins sees connection-refused rather than a 503. Set this to a host's readiness poll interval (a few seconds) for a clean drain.

func WithShutdownTimeout

func WithShutdownTimeout(timeout time.Duration) Option

WithShutdownTimeout sets the bounded shutdown timeout.

type WorkerFlags added in v0.5.0

type WorkerFlags struct {
	jobs.WorkerOptions
	// MetricsAddr, when set, serves /metrics (job outcomes and queue depth)
	// and /livez on that address while the worker runs.
	MetricsAddr string
}

WorkerFlags are the parsed worker flags: the worker's options, plus where to serve its metrics.

func ParseWorkerFlags added in v0.5.0

func ParseWorkerFlags(args []string, output io.Writer) (WorkerFlags, error)

ParseWorkerFlags parses the worker flags `gombit worker` and `./server worker` share: --queue (repeatable or comma-separated, in priority order), --concurrency, --lease, --shutdown-timeout, and --metrics-addr.

Jump to

Keyboard shortcuts

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