Documentation
¶
Overview ¶
Package gas provides the core framework: DI container, App/Worker lifecycle, Router with ownership tracking, EventBus, ConfigProvider, and the provider interfaces (Logger, Authenticator, StorageProvider, ...) that other gasmod modules implement.
See the module README for usage examples and design rationale.
SPDX-License-Identifier: MIT
Index ¶
- Variables
- func ApplyEnqueueOptions(opts []EnqueueOption) (delay time.Duration, groupID, dedupeID string, attrs map[string]string)
- func ApplyStorageOptions(opts []StorageOption) (bucket, contentType string, metadata map[string]string)
- func CacheControl(opt ...CacheControlOption) func(next http.Handler) http.Handler
- func Emit[T any](bus *EventBus, event Event[T], data T) *sync.WaitGroup
- func MetadataValue[T any](m PrincipalMetadata, key string) (T, bool)
- func MustResolve[T any](r Resolver) T
- func MustResolveFromRequestScope[T any](r *http.Request) T
- func RegisterCtor[T any](c *ServiceContainer, ctor any, lifetime ServiceLifetime)
- func RegisterInstance[T any](c *ServiceContainer, val T)
- func RequestLogger[T Logger](opt ...RequestLoggerOption) func(next http.Handler) http.Handler
- func Resolve[T any](r Resolver) (T, error)
- func ResolveFromRequestScope[T any](r *http.Request) (T, error)
- func SecurityHeaders(opt ...SecurityHeadersOption) func(next http.Handler) http.Handler
- func Subscribe[T any](bus *EventBus, event Event[T], handler func(T))
- func SubscribeWithOwner[T any](bus *EventBus, service string, event Event[T], handler func(T))
- func WithLogger(ctx context.Context, logger Logger) context.Context
- func WithPrincipal(ctx context.Context, principal Principal) context.Context
- func WithRequestScope(ctx context.Context, scope *Scope) context.Context
- type App
- type AppConfigUpdatedPayload
- type AppOption
- type Authenticator
- type Authorizer
- type BasePrincipalMetadata
- type CacheControlOption
- func WithCacheControlImmutable() CacheControlOption
- func WithCacheControlMaxAge(val time.Duration) CacheControlOption
- func WithCacheControlMustRevalidate() CacheControlOption
- func WithCacheControlMustUnderstand() CacheControlOption
- func WithCacheControlNoCache() CacheControlOption
- func WithCacheControlNoStore() CacheControlOption
- func WithCacheControlNoTransform() CacheControlOption
- func WithCacheControlPath(val string) CacheControlOption
- func WithCacheControlPathPrefix(val string) CacheControlOption
- func WithCacheControlPathPrefixes(val []string) CacheControlOption
- func WithCacheControlPathSuffix(val string) CacheControlOption
- func WithCacheControlPathSuffixes(val []string) CacheControlOption
- func WithCacheControlPaths(val []string) CacheControlOption
- func WithCacheControlPrivate() CacheControlOption
- func WithCacheControlProxyRevalidate() CacheControlOption
- func WithCacheControlPublic() CacheControlOption
- func WithCacheControlSMaxAge(val time.Duration) CacheControlOption
- func WithCacheControlStaleIfError(val time.Duration) CacheControlOption
- func WithCacheControlStaleWhileRevalidate(val time.Duration) CacheControlOption
- type CacheControlOptions
- type CacheProvider
- type Config
- type ConfigProvider
- type Context
- type ContextOption
- type DatabaseProvider
- type Email
- type EmailProvider
- type EnqueueOption
- type ErrorHandler
- type Event
- type EventBus
- type HealthProvider
- type HealthReporter
- type Job
- type JobQueueProvider
- type LogEvent
- type Logger
- type LoggerContext
- type Middleware
- type Migration
- type MigrationManager
- type MutableLoggerContext
- type NopLogEvent
- func (e *NopLogEvent) Any(string, any) LogEvent
- func (e *NopLogEvent) Bool(string, bool) LogEvent
- func (e *NopLogEvent) Duration(string, time.Duration) LogEvent
- func (e *NopLogEvent) Err(string, error) LogEvent
- func (e *NopLogEvent) Float64(string, float64) LogEvent
- func (e *NopLogEvent) Int(string, int) LogEvent
- func (e *NopLogEvent) Int64(string, int64) LogEvent
- func (e *NopLogEvent) Send()
- func (e *NopLogEvent) Str(string, string) LogEvent
- type NopLogger
- func (l *NopLogger) Debug(string) LogEvent
- func (l *NopLogger) Error(string) LogEvent
- func (l *NopLogger) Flush()
- func (l *NopLogger) Info(string) LogEvent
- func (l *NopLogger) SetBaseFields() MutableLoggerContext
- func (l *NopLogger) Trace(string) LogEvent
- func (l *NopLogger) Warn(string) LogEvent
- func (l *NopLogger) With() LoggerContext
- type NopLoggerContext
- func (c *NopLoggerContext) Any(string, any) LoggerContext
- func (c *NopLoggerContext) Bool(string, bool) LoggerContext
- func (c *NopLoggerContext) Duration(string, time.Duration) LoggerContext
- func (c *NopLoggerContext) Err(string, error) LoggerContext
- func (c *NopLoggerContext) Float64(string, float64) LoggerContext
- func (c *NopLoggerContext) Int(string, int) LoggerContext
- func (c *NopLoggerContext) Int64(string, int64) LoggerContext
- func (c *NopLoggerContext) Logger() Logger
- func (c *NopLoggerContext) Str(string, string) LoggerContext
- type NopLoggerCtor
- type NopMutableLoggerContext
- func (c *NopMutableLoggerContext) Any(string, any) MutableLoggerContext
- func (c *NopMutableLoggerContext) Apply()
- func (c *NopMutableLoggerContext) Bool(string, bool) MutableLoggerContext
- func (c *NopMutableLoggerContext) Duration(string, time.Duration) MutableLoggerContext
- func (c *NopMutableLoggerContext) Err(string, error) MutableLoggerContext
- func (c *NopMutableLoggerContext) Float64(string, float64) MutableLoggerContext
- func (c *NopMutableLoggerContext) Int(string, int) MutableLoggerContext
- func (c *NopMutableLoggerContext) Int64(string, int64) MutableLoggerContext
- func (c *NopMutableLoggerContext) Str(string, string) MutableLoggerContext
- type ObjectInfo
- type Option
- type Principal
- type PrincipalMetadata
- type PrincipalRevoker
- type ReadyProvider
- type ReadyReporter
- type RegisteredRoute
- type RequestLoggerOption
- type RequestLoggerOptions
- type Resolver
- type Result
- type Router
- func (r *Router) Group(fn func(sub *Router))
- func (r *Router) Handle(service, method, path string, handler any, middleware ...Middleware)
- func (r *Router) Mux() chi.Router
- func (r *Router) NamedMiddleware() map[string]string
- func (r *Router) NotFound(service string, handler any)
- func (r *Router) Register(service, name string, mw func(http.Handler) http.Handler)
- func (r *Router) RemoveByModule(service string)
- func (r *Router) Route(pattern string, fn func(sub *Router))
- func (r *Router) Routes() map[string][]RegisteredRoute
- func (r *Router) Seal()
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
- func (r *Router) SetErrorHandler(h ErrorHandler)
- func (r *Router) Use(middleware ...Middleware)
- func (r *Router) UseMiddlewareByName(middleware string)
- func (r *Router) UseMiddlewareFunc(middleware func(http.Handler) http.Handler)
- type Rows
- type Scope
- type SecurityHeadersOption
- func WithSecurityHeadersContentSecurityPolicy(val string) SecurityHeadersOption
- func WithSecurityHeadersContentTypeOptions(val string) SecurityHeadersOption
- func WithSecurityHeadersCrossOriginOpenerPolicy(val string) SecurityHeadersOption
- func WithSecurityHeadersCrossOriginResourcePolicy(val string) SecurityHeadersOption
- func WithSecurityHeadersFrameOptions(val string) SecurityHeadersOption
- func WithSecurityHeadersPermissionsPolicy(val string) SecurityHeadersOption
- func WithSecurityHeadersReferrerPolicy(val string) SecurityHeadersOption
- func WithSecurityHeadersStrictTransportSecurity(val string) SecurityHeadersOption
- type SecurityHeadersOptions
- type ServerSettings
- type Service
- type ServiceContainer
- type ServiceLifetime
- type StorageObject
- type StorageOption
- type StorageProvider
- type SystemAllServicesInitializedPayload
- type SystemServerShuttingDownPayload
- type SystemServiceClosedPayload
- type SystemServiceInitializedPayload
- type SystemShuttingDownPayload
- type TemplateProvider
- type TemplatedEmail
- type UIProvider
- type Worker
- func (w *Worker) ActiveServices() []string
- func (w *Worker) ActiveServicesMap() map[string]Service
- func (w *Worker) CheckHealth(ctx context.Context) map[string]error
- func (w *Worker) CheckReady(ctx context.Context) map[string]error
- func (w *Worker) CloseService(name string) error
- func (w *Worker) ConfigProvider() ConfigProvider
- func (w *Worker) EventBus() *EventBus
- func (w *Worker) InitServices() (err error)
- func (w *Worker) MigrationManager() MigrationManager
- func (w *Worker) RestartService(name string) error
- func (w *Worker) Run() error
- func (w *Worker) ServiceContainer() *ServiceContainer
- func (w *Worker) Shutdown() error
- func (w *Worker) Start() error
- type WorkerOption
- func WithReadyFunc(fn func(*ServiceContainer) error) WorkerOption
- func WithScopedService[T any](ctor any) WorkerOption
- func WithService[T any](ctor any, lifetime ServiceLifetime) WorkerOption
- func WithServiceInstance[T any](val T) WorkerOption
- func WithSingletonService[T any](ctor any) WorkerOption
- func WithTransientService[T any](ctor any) WorkerOption
Constants ¶
This section is empty.
Variables ¶
var AppConfigUpdated = Event[AppConfigUpdatedPayload]{Name: "gas:config-updated"}
AppConfigUpdated is emitted when the app config is updated.
var SystemAllServicesInitialized = Event[SystemAllServicesInitializedPayload]{Name: "gas:all-services-initialized"}
SystemAllServicesInitialized is emitted when all services have been successfully initialized.
var SystemServerShuttingDown = Event[SystemServerShuttingDownPayload]{Name: "gas:server-shutting-down"}
SystemServerShuttingDown is emitted when the HTTP server is shutting down. For code that should run on any shutdown (not just HTTP), subscribe to SystemShuttingDown instead.
var SystemServiceClosed = Event[SystemServiceClosedPayload]{Name: "gas:service-closed"}
SystemServiceClosed is emitted when a service is closed at runtime.
var SystemServiceInitialized = Event[SystemServiceInitializedPayload]{Name: "gas:service-initialized"}
SystemServiceInitialized is emitted when a service is (re-)initialized at runtime.
var SystemShuttingDown = Event[SystemShuttingDownPayload]{Name: "gas:shutting-down"}
SystemShuttingDown is emitted when a Worker or App begins its shutdown sequence. It fires for both HTTP (App) and non-HTTP (Worker) workloads.
Functions ¶
func ApplyEnqueueOptions ¶
func ApplyEnqueueOptions(opts []EnqueueOption) (delay time.Duration, groupID, dedupeID string, attrs map[string]string)
ApplyEnqueueOptions resolves variadic EnqueueOption values into a concrete enqueueOptions struct. Implementations call this inside their Enqueue method.
func ApplyStorageOptions ¶
func ApplyStorageOptions(opts []StorageOption) (bucket, contentType string, metadata map[string]string)
ApplyStorageOptions resolves variadic StorageOption values into their individual fields. Implementations call this inside their methods.
func CacheControl ¶
func CacheControl(opt ...CacheControlOption) func(next http.Handler) http.Handler
CacheControl is middleware that sets the Cache-Control response header based on path matching rules and configured directives. If no path filters are specified, the header is applied to all requests. If no directives are specified, the middleware passes through without setting any header.
func MetadataValue ¶
func MetadataValue[T any](m PrincipalMetadata, key string) (T, bool)
MetadataValue is a type-safe helper that retrieves a typed value from PrincipalMetadata. It returns the value and true if the key exists and the type assertion succeeds, or the zero value and false otherwise.
func MustResolve ¶
MustResolve is like Resolve but panics if the service cannot be resolved.
func MustResolveFromRequestScope ¶
MustResolveFromRequestScope retrieves a service of type T from the request's Scope and panics if it cannot be resolved.
func RegisterCtor ¶
func RegisterCtor[T any](c *ServiceContainer, ctor any, lifetime ServiceLifetime)
RegisterCtor registers a constructor for type T with an optional lifetime. Constructor signature: func(DepA, DepB, ...) T or func(DepA, DepB, ...) (T, error)
Panics if lifetime is Transient and T implements Service — transient services cannot have managed lifecycles. Use Singleton or Scoped instead.
func RegisterInstance ¶
func RegisterInstance[T any](c *ServiceContainer, val T)
RegisterInstance registers a pre-built value. Treated as a singleton.
func RequestLogger ¶
RequestLogger is middleware that logs HTTP requests and responses using a scoped Logger resolved from the request's DI scope. It logs method, path, status, bytes written, duration, and remote address. Responses with status >= 400 are logged at error level; all others at info level.
The type parameter T must be the concrete Logger implementation registered in the DI container. If the logger cannot be resolved, the middleware passes through silently.
When appendRequestID is enabled (the default), the middleware expects chi's RequestID middleware to be mounted upstream so that a request ID is available via middleware.GetReqID.
func Resolve ¶
Resolve retrieves or builds a service of type T from a Resolver (either *ServiceContainer or *Scope).
func ResolveFromRequestScope ¶
ResolveFromRequestScope retrieves or builds a service of type T from the per-request scope in the provided *http.Request.
func SecurityHeaders ¶
func SecurityHeaders(opt ...SecurityHeadersOption) func(next http.Handler) http.Handler
SecurityHeaders is middleware that sets common security-related HTTP response headers. It applies secure defaults out of the box (nosniff, DENY framing, strict referrer policy, and restrictive permissions policy). Use the functional options to override individual header values, or pass an empty string to disable a specific header.
func SubscribeWithOwner ¶
SubscribeWithOwner registers a typed handler for an event with service ownership tracking.
func WithLogger ¶
WithLogger returns a copy of ctx with the given Logger attached.
func WithPrincipal ¶
WithPrincipal stores a Principal in the given context.
Types ¶
type App ¶
type App struct {
*Worker
// contains filtered or unexported fields
}
App manages service lifecycle, the HTTP server, and graceful shutdown. It embeds a Worker for DI, events, migrations, and service management, and adds routing, CSRF protection, and an HTTP listener on top.
func NewApp ¶
NewApp creates an App with the given options. Router and EventBus are created internally and registered in the container.
func (*App) Handler ¶
Handler returns the fully wrapped http.Handler used by the App's server (router behind CSRF protection). Useful for embedding the App in tests or in an externally managed listener.
func (*App) Run ¶
Run initializes all services, runs pending migrations, starts the HTTP server, and blocks until a shutdown signal is received.
func (*App) Serve ¶
Serve starts the HTTP server and blocks until it stops. A clean shutdown (http.ErrServerClosed) returns nil; any other listener error is returned.
func (*App) Server ¶
Server returns the App's *http.Server, constructing it on first call from the current Config. The instance is cached and safe to call concurrently.
type AppConfigUpdatedPayload ¶
type AppConfigUpdatedPayload struct {
Config Config
}
AppConfigUpdatedPayload carries the updated config.
type AppOption ¶
type AppOption func(*App)
AppOption configures HTTP-specific aspects of an App (error handler, CSRF, trusted origins). Only NewApp accepts AppOption values; passing one to NewWorker panics.
func WithCSRFDenyHandler ¶
WithCSRFDenyHandler sets the handler invoked when a cross-origin request is rejected by CSRF protection. The default handler returns 403 Forbidden.
func WithCSRFInsecureBypassPattern ¶
WithCSRFInsecureBypassPattern adds a URL path pattern that bypasses CSRF cross-origin protection. Use only for endpoints that require unauthenticated cross-origin access and implement their own request validation (e.g. webhook receivers).
func WithErrorHandler ¶
func WithErrorHandler(h ErrorHandler) AppOption
WithErrorHandler configures the function that converts DI-aware handler errors into HTTP responses.
func WithTrustedOrigin ¶
WithTrustedOrigin adds an origin that is permitted to make cross-origin non-safe requests (POST, PUT, PATCH, DELETE, etc.). The origin must be an absolute URL with a scheme and host, e.g. "https://app.example.com". Panics if the origin is not a valid absolute URL.
type Authenticator ¶
type Authenticator interface {
Authenticate(ctx context.Context, r *http.Request) (Principal, error)
}
Authenticator extracts a Principal from an HTTP request. Implementations may use JWTs, server-side sessions, API keys, or any other credential scheme.
type Authorizer ¶
type Authorizer interface {
Authorize(ctx context.Context, principal Principal, action, resource string) error
}
Authorizer decides whether a Principal is allowed to perform an action on a resource. It is a separate concern from authentication — an Authenticator identifies who the caller is, while an Authorizer enforces what they can do.
type BasePrincipalMetadata ¶
BasePrincipalMetadata is a map-based implementation of PrincipalMetadata.
func (BasePrincipalMetadata) Value ¶
func (m BasePrincipalMetadata) Value(key string) any
Value returns the metadata value for the given key, or nil if not present.
type CacheControlOption ¶
type CacheControlOption func(*CacheControlOptions)
CacheControlOption is a functional option for configuring CacheControl.
func WithCacheControlImmutable ¶
func WithCacheControlImmutable() CacheControlOption
WithCacheControlImmutable appends the "immutable" directive.
func WithCacheControlMaxAge ¶
func WithCacheControlMaxAge(val time.Duration) CacheControlOption
WithCacheControlMaxAge appends a "max-age" directive with the given duration.
func WithCacheControlMustRevalidate ¶
func WithCacheControlMustRevalidate() CacheControlOption
WithCacheControlMustRevalidate appends the "must-revalidate" directive.
func WithCacheControlMustUnderstand ¶
func WithCacheControlMustUnderstand() CacheControlOption
WithCacheControlMustUnderstand appends the "must-understand" directive.
func WithCacheControlNoCache ¶
func WithCacheControlNoCache() CacheControlOption
WithCacheControlNoCache appends the "no-cache" directive.
func WithCacheControlNoStore ¶
func WithCacheControlNoStore() CacheControlOption
WithCacheControlNoStore appends the "no-store" directive.
func WithCacheControlNoTransform ¶
func WithCacheControlNoTransform() CacheControlOption
WithCacheControlNoTransform appends the "no-transform" directive.
func WithCacheControlPath ¶
func WithCacheControlPath(val string) CacheControlOption
WithCacheControlPath adds an exact path that should receive the Cache-Control header.
func WithCacheControlPathPrefix ¶
func WithCacheControlPathPrefix(val string) CacheControlOption
WithCacheControlPathPrefix adds a path prefix to match against. Any request whose path starts with this prefix will receive the Cache-Control header.
func WithCacheControlPathPrefixes ¶
func WithCacheControlPathPrefixes(val []string) CacheControlOption
WithCacheControlPathPrefixes adds multiple path prefixes to match against.
func WithCacheControlPathSuffix ¶
func WithCacheControlPathSuffix(val string) CacheControlOption
WithCacheControlPathSuffix adds a path suffix to match against (e.g., ".css", ".js"). Any request whose path ends with this suffix will receive the Cache-Control header.
func WithCacheControlPathSuffixes ¶
func WithCacheControlPathSuffixes(val []string) CacheControlOption
WithCacheControlPathSuffixes adds multiple path suffixes to match against.
func WithCacheControlPaths ¶
func WithCacheControlPaths(val []string) CacheControlOption
WithCacheControlPaths adds multiple exact paths that should receive the Cache-Control header.
func WithCacheControlPrivate ¶
func WithCacheControlPrivate() CacheControlOption
WithCacheControlPrivate appends the "private" directive.
func WithCacheControlProxyRevalidate ¶
func WithCacheControlProxyRevalidate() CacheControlOption
WithCacheControlProxyRevalidate appends the "proxy-revalidate" directive.
func WithCacheControlPublic ¶
func WithCacheControlPublic() CacheControlOption
WithCacheControlPublic appends the "public" directive.
func WithCacheControlSMaxAge ¶
func WithCacheControlSMaxAge(val time.Duration) CacheControlOption
WithCacheControlSMaxAge appends an "s-maxage" directive (shared/CDN cache max age).
func WithCacheControlStaleIfError ¶
func WithCacheControlStaleIfError(val time.Duration) CacheControlOption
WithCacheControlStaleIfError appends a "stale-if-error" directive.
func WithCacheControlStaleWhileRevalidate ¶
func WithCacheControlStaleWhileRevalidate(val time.Duration) CacheControlOption
WithCacheControlStaleWhileRevalidate appends a "stale-while-revalidate" directive.
type CacheControlOptions ¶
type CacheControlOptions struct {
// contains filtered or unexported fields
}
CacheControlOptions configures the behavior of the CacheControl middleware.
type CacheProvider ¶
type CacheProvider interface {
Get(ctx context.Context, key string) ([]byte, error)
Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
Delete(ctx context.Context, key string) error
Exists(ctx context.Context, key string) (bool, error)
}
CacheProvider abstracts key-value caching. Implemented by in-memory, Redis, Valkey, or any other cache service.
type Config ¶
type Config struct {
// Embedded GasEnv
env.WithGasEnv
Server ServerSettings
}
Config holds server-level configuration passed from the host server to the App. Sensible defaults are applied via DefaultConfig().
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with sensible defaults.
type ConfigProvider ¶
type ConfigProvider interface {
SetDefault(key string, value any)
SetDefaults(values any) error
Set(key string, value any)
Bind(dest any, options ...config.BindOption) error
Get(key string) any
Find(key string) (value any, exist bool)
Values() map[string]any
}
ConfigProvider defines the config struct API, used by other modules that needs access to the config provider.
type Context ¶
type Context interface {
context.Context
// ResponseWriter returns the underlying http.ResponseWriter.
ResponseWriter() http.ResponseWriter
// Request returns the underlying *http.Request.
Request() *http.Request
// JSON serializes v as JSON and writes it with the given status code.
JSON(status int, v any) error
// XML serializes v as XML and writes it with the given status code.
// Uses content type "application/xml; charset=utf-8".
XML(status int, v any) error
// RSS serializes v as XML with content type "application/rss+xml; charset=utf-8".
RSS(status int, v any) error
// HTML writes an HTML response with the given status code and content string.
HTML(status int, s string) error
// Text writes a plain-text response with the given status code.
Text(status int, s string) error
// NoContent writes a 204 No Content response.
NoContent() error
// Redirect sends an HTTP redirect to the given URL with the given status code.
Redirect(status int, url string)
// Param returns the URL parameter value by name (chi.URLParam).
Param(key string) string
// Query returns the query string parameter value by name.
Query(key string) string
// Header returns the request header value by name.
Header(key string) string
// SetHeader sets a response header.
SetHeader(key, value string)
// BindJSON decodes the request body as JSON into dest and performs automatic validation
// using the configured validator.
BindJSON(dest any) error
// BindForm binds form data from the HTTP request to the provided destination object
// and performs automatic validation using the configured validator.
BindForm(dest any) error
// Validator returns a pointer to the validator.Validate instance used for request validation.
Validator() *validator.Validate
// FormDecoder returns a preconfigured *schema.Decoder instance for decoding form data into structs.
FormDecoder() *schema.Decoder
}
Context is the first parameter of every DI-aware handler. It wraps the HTTP response writer and request into a single value. The per-request scope is accessible via RequestScope(c.Request()) — the adapter resolves dependencies automatically, so handlers rarely need to access the scope directly.
func NewContext ¶
func NewContext(parent context.Context, w http.ResponseWriter, r *http.Request, opts ...ContextOption) Context
NewContext creates a Context from the standard HTTP pair.
type ContextOption ¶
type ContextOption func(*reqContext)
ContextOption is a functional option used to modify or extend the behavior of a reqContext at creation time.
func WithFormDecoder ¶
func WithFormDecoder(d *schema.Decoder) ContextOption
WithFormDecoder sets a custom form decoder for the reqContext using the provided *schema.Decoder instance.
func WithValidate ¶
func WithValidate(v *validator.Validate) ContextOption
WithValidate returns a ContextOption that sets the provided *validator.Validate instance to the reqContext.
type DatabaseProvider ¶
type DatabaseProvider interface {
DB() *sql.DB
Driver() string
Ping(ctx context.Context) error
Query(ctx context.Context, query string, args ...any) (Rows, error)
Exec(ctx context.Context, query string, args ...any) (Result, error)
BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
WithTx(ctx context.Context, opts *sql.TxOptions, fn func(*sql.Tx) error) (err error)
}
DatabaseProvider abstracts database access. Implemented by gas-database or any other database service. DB() exposes the underlying *sql.DB so that sqlc-generated code and transactions can use it directly.
type Email ¶
type Email struct {
From string
ReplyTo string
Subject string
TextBody string
HTMLBody string
Headers map[string]string
To []string
Cc []string
Bcc []string
}
Email represents an email message.
type EmailProvider ¶
type EmailProvider interface {
Send(ctx context.Context, msg *Email) error
SendFromTemplate(ctx context.Context, msg *TemplatedEmail) error
}
EmailProvider abstracts email sending.
type EnqueueOption ¶
type EnqueueOption func(*enqueueOptions)
EnqueueOption configures an Enqueue call.
func WithDedupeID ¶
func WithDedupeID(id string) EnqueueOption
WithDedupeID sets a deduplication identifier.
func WithDelay ¶
func WithDelay(d time.Duration) EnqueueOption
WithDelay sets an initial delay before the job becomes visible to consumers.
func WithGroupID ¶
func WithGroupID(id string) EnqueueOption
WithGroupID sets the message group for FIFO queue ordering.
func WithJobAttributes ¶
func WithJobAttributes(attrs map[string]string) EnqueueOption
WithJobAttributes attaches provider-specific key-value metadata to the job.
type ErrorHandler ¶
ErrorHandler converts a handler error into an HTTP response.
type EventBus ¶
type EventBus struct {
// contains filtered or unexported fields
}
EventBus is a publish/subscribe message bus with service ownership tracking.
func (*EventBus) Emit ¶
Emit dispatches an event to all subscribers concurrently and returns a WaitGroup.
func (*EventBus) RemoveByModule ¶
RemoveByModule removes all subscriptions registered by the given service.
func (*EventBus) Subscribe ¶
Subscribe registers a handler for an event without service ownership. Use SubscribeWithOwner when subscribing from a service so that RemoveByModule can clean up subscriptions.
func (*EventBus) SubscribeWithOwner ¶
SubscribeWithOwner registers a handler for an event with service ownership tracking. The base server uses this ownership info during kill-switch to remove all subscriptions belonging to a closed service.
type HealthProvider ¶
HealthProvider aggregates health signals across all active services that implement HealthReporter. The returned map keys are service names; a nil value indicates a healthy service.
type HealthReporter ¶
HealthReporter is implemented by services that can report their own health. Answers the question "am I alive?" — a failure here signals that the process is in a broken state that a restart would resolve (lost connection that won't recover, corrupt internal state, deadlock). Maps to a Kubernetes livenessProbe. A nil return means healthy; a non-nil error describes the failure.
type Job ¶
type Job struct {
ID string
ReceiptHandle string // opaque token used by Ack/Nack
Attributes map[string]string // provider-specific metadata
Body []byte
}
Job represents a message received from a queue.
type JobQueueProvider ¶
type JobQueueProvider interface {
Enqueue(ctx context.Context, queue string, payload []byte, opts ...EnqueueOption) error
Dequeue(ctx context.Context, queue string, maxMessages int, wait time.Duration) ([]Job, error)
Ack(ctx context.Context, queue string, job Job) error
Nack(ctx context.Context, queue string, job Job) error
}
JobQueueProvider abstracts async job/message queue processing. Implemented by gas-queue-sqs or any other queue service. The interface is pull-based: consumers call Dequeue in their own worker loop and acknowledge results with Ack/Nack.
type LogEvent ¶
type LogEvent interface {
Str(key, val string) LogEvent
Int(key string, val int) LogEvent
Int64(key string, val int64) LogEvent
Float64(key string, val float64) LogEvent
Bool(key string, val bool) LogEvent
Err(key string, val error) LogEvent
Duration(key string, val time.Duration) LogEvent
Any(key string, val any) LogEvent
// Send finalizes and emits the log event.
Send()
}
LogEvent is a single structured log entry. Field methods return the same LogEvent for chaining. Call Send to finalize and emit the event.
type Logger ¶
type Logger interface {
// Trace starts a log event at the TRACE level.
Trace(msg string) LogEvent
// Debug starts a log event at the DEBUG level.
Debug(msg string) LogEvent
// Info starts a log event at the INFO level.
Info(msg string) LogEvent
// Warn starts a log event at the WARN level.
Warn(msg string) LogEvent
// Error starts a log event at the ERROR level.
Error(msg string) LogEvent
// With returns a LoggerContext for building a sub-logger with persistent fields.
With() LoggerContext
// SetBaseFields returns a MutableLoggerContext for attaching persistent fields
// directly to this logger instance. Unlike With, which branches into a new logger,
// SetBaseFields mutates the receiver so that all subsequent log events carry the
// accumulated fields. Intended for use by request-scoped middleware.
SetBaseFields() MutableLoggerContext
// Flush writes any buffered log entries to the underlying output.
Flush()
}
Logger is the provider interface for structured logging in the Gas ecosystem. Implementations produce LogEvent values at a given severity level. Each method returns a LogEvent that can be enriched with typed fields before calling Send.
Use With to derive a sub-logger that carries persistent fields across all subsequent log events.
Call Flush to ensure all buffered log entries are written (e.g. before shutdown).
func LoggerFromContext ¶
LoggerFromContext returns the Logger stored in ctx, or nil if none is present.
type LoggerContext ¶
type LoggerContext interface {
Str(key, val string) LoggerContext
Int(key string, val int) LoggerContext
Int64(key string, val int64) LoggerContext
Float64(key string, val float64) LoggerContext
Bool(key string, val bool) LoggerContext
Err(key string, val error) LoggerContext
Duration(key string, val time.Duration) LoggerContext
Any(key string, val any) LoggerContext
// Logger returns a new Logger that includes all fields added to this context.
Logger() Logger
}
LoggerContext is a builder for deriving a sub-logger with persistent fields. Each field method returns the same LoggerContext for chaining. Call Logger to obtain the resulting Logger that carries all accumulated fields.
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
Middleware represents either a named middleware (resolved from the router's registry at apply time) or an inline middleware function.
func MiddlewareByName ¶
func MiddlewareByName(name string) Middleware
MiddlewareByName creates a Middleware that will be resolved by name from the router's internal registry when applied.
func MiddlewareFunc ¶
func MiddlewareFunc(fn func(http.Handler) http.Handler) Middleware
MiddlewareFunc creates a Middleware that wraps an inline handler function directly. The middleware will be anonymous and omitted from the route map. Use MiddlewareFuncWithName to give it a display name.
func MiddlewareFuncWithName ¶
MiddlewareFuncWithName creates a named inline Middleware. The name appears in the route map alongside routes that this middleware applies to.
type MigrationManager ¶
type MigrationManager interface {
Service
// Register adds a migration and tracks which service owns it.
Register(service string, m Migration)
// RegisterSlice adds multiple migrations at once for the given service.
RegisterSlice(service string, migrations []Migration)
// RegisterFS reads .up.sql/.down.sql files from an fs.FS and registers
// them as migrations for the given service. Files must follow the naming
// convention: {version}_{description}.up.sql / {version}_{description}.down.sql
// (e.g. 20250216_001_create_users.up.sql).
RegisterFS(service string, fsys fs.FS) error
// RunPending applies all unapplied migrations in global version order.
// If any migration is marked dirty, execution is blocked until the
// dirty state is manually resolved.
RunPending() error
// Down reverses the last n applied migrations in reverse version order.
Down(n int) error
}
MigrationManager is the interface for registering and executing database migrations. Services call Register during Init() to declare their migrations. The implementation lives in a separate service (gas-migrate) and is wired in by the App.
type MutableLoggerContext ¶
type MutableLoggerContext interface {
Str(key, val string) MutableLoggerContext
Int(key string, val int) MutableLoggerContext
Int64(key string, val int64) MutableLoggerContext
Float64(key string, val float64) MutableLoggerContext
Bool(key string, val bool) MutableLoggerContext
Err(key string, val error) MutableLoggerContext
Duration(key string, val time.Duration) MutableLoggerContext
Any(key string, val any) MutableLoggerContext
// Apply mutates the originating Logger in place with all accumulated fields.
Apply()
}
MutableLoggerContext is a builder for attaching persistent fields directly to an existing Logger instance. Unlike LoggerContext (returned by With), which produces a new branched Logger, MutableLoggerContext.Apply() mutates the receiver in place. Intended for use in request-scoped middleware where the same Logger instance is shared across the whole request.
type NopLogEvent ¶
type NopLogEvent struct{}
NopLogEvent is a LogEvent that discards all fields and performs no action on Send. All methods return the receiver for chaining.
func (*NopLogEvent) Any ¶
func (e *NopLogEvent) Any(string, any) LogEvent
Any adds a key-value pair to the event, where the value can be of any type, returning the event for chaining.
func (*NopLogEvent) Bool ¶
func (e *NopLogEvent) Bool(string, bool) LogEvent
Bool adds a boolean field to the log event and returns the event for method chaining.
func (*NopLogEvent) Duration ¶
func (e *NopLogEvent) Duration(string, time.Duration) LogEvent
Duration adds a field with a duration value to the log entry, identified by the given key.
func (*NopLogEvent) Err ¶
func (e *NopLogEvent) Err(string, error) LogEvent
Err adds an error field to the log event with the specified key and value. Returns the log event for chaining.
func (*NopLogEvent) Float64 ¶
func (e *NopLogEvent) Float64(string, float64) LogEvent
Float64 sets a float64 value for the specified key in the log event. It returns the LogEvent instance for chaining.
func (*NopLogEvent) Int ¶
func (e *NopLogEvent) Int(string, int) LogEvent
Int adds an integer field to the log event with the provided key and value, returning the LogEvent for chaining.
func (*NopLogEvent) Int64 ¶
func (e *NopLogEvent) Int64(string, int64) LogEvent
Int64 adds an int64 field to the log event with the specified key and value. It returns the LogEvent for chaining.
func (*NopLogEvent) Send ¶
func (e *NopLogEvent) Send()
Send finalizes the log event. In NopLogEvent, it performs no action and discards the event.
type NopLogger ¶
type NopLogger struct{}
NopLogger is a Logger implementation that silently discards all log output. It uses a singleton pattern — all instances share the same underlying value, resulting in zero allocations per log call.
func (*NopLogger) Debug ¶
Debug logs a debug-level message and returns a no-op LogEvent for chaining.
func (*NopLogger) Error ¶
Error logs an error-level message with no operational effect, returning a no-op LogEvent.
func (*NopLogger) Flush ¶
func (l *NopLogger) Flush()
Flush performs no operation as NopLogger discards all log output without buffering.
func (*NopLogger) SetBaseFields ¶
func (l *NopLogger) SetBaseFields() MutableLoggerContext
SetBaseFields returns a no-op MutableLoggerContext associated with the NopLogger instance.
func (*NopLogger) Trace ¶
Trace creates a no-op log event for a trace-level message and silently discards it.
func (*NopLogger) With ¶
func (l *NopLogger) With() LoggerContext
With creates a new LoggerContext for deriving a sub-logger with persistent fields across log events.
type NopLoggerContext ¶
type NopLoggerContext struct{}
NopLoggerContext is a LoggerContext that discards all fields. All methods return the receiver for chaining and Logger returns a NopLogger.
func (*NopLoggerContext) Any ¶
func (c *NopLoggerContext) Any(string, any) LoggerContext
Any adds a field with the given key and value to the context, supporting any type, and returns the LoggerContext.
func (*NopLoggerContext) Bool ¶
func (c *NopLoggerContext) Bool(string, bool) LoggerContext
Bool adds a boolean field to the logging context under the specified key for structured logging.
func (*NopLoggerContext) Duration ¶
func (c *NopLoggerContext) Duration(string, time.Duration) LoggerContext
Duration adds a time.Duration field with the specified key and value to the logging context and returns it.
func (*NopLoggerContext) Err ¶
func (c *NopLoggerContext) Err(string, error) LoggerContext
Err adds an error field to the logger context with the specified key and error value, returning the same context.
func (*NopLoggerContext) Float64 ¶
func (c *NopLoggerContext) Float64(string, float64) LoggerContext
Float64 adds a float64 field with the specified key and value to the context and returns the LoggerContext for chaining.
func (*NopLoggerContext) Int ¶
func (c *NopLoggerContext) Int(string, int) LoggerContext
Int adds an integer field to the logger context with the specified key. Returns the same LoggerContext for chaining.
func (*NopLoggerContext) Int64 ¶
func (c *NopLoggerContext) Int64(string, int64) LoggerContext
Int64 adds a key-value pair with an int64 value to the log context and returns the updated LoggerContext.
func (*NopLoggerContext) Logger ¶
func (c *NopLoggerContext) Logger() Logger
Logger returns a no-op Logger instance that discards all log events.
func (*NopLoggerContext) Str ¶
func (c *NopLoggerContext) Str(string, string) LoggerContext
Str adds a string key-value pair to the logger context and returns the same context for chaining.
type NopLoggerCtor ¶
type NopLoggerCtor func() *NopLogger
NopLoggerCtor defines a constructor function that returns a nop-logger implementing the Logger interface.
func NewNopLogger ¶
func NewNopLogger() NopLoggerCtor
NewNopLogger returns a NopLoggerCtor that constructs a nop-logger implementing the Logger interface.
type NopMutableLoggerContext ¶
type NopMutableLoggerContext struct{}
NopMutableLoggerContext is a MutableLoggerContext that discards all fields. All methods return the receiver for chaining and Apply is a no-op.
func (*NopMutableLoggerContext) Any ¶
func (c *NopMutableLoggerContext) Any(string, any) MutableLoggerContext
Any adds a custom key-value pair with a generic value to the context and returns the current MutableLoggerContext.
func (*NopMutableLoggerContext) Apply ¶
func (c *NopMutableLoggerContext) Apply()
Apply performs a no-op operation and returns without modifying any state or producing side effects.
func (*NopMutableLoggerContext) Bool ¶
func (c *NopMutableLoggerContext) Bool(string, bool) MutableLoggerContext
Bool adds a boolean field with the given key and value to the logger context and returns the context for chaining.
func (*NopMutableLoggerContext) Duration ¶
func (c *NopMutableLoggerContext) Duration(string, time.Duration) MutableLoggerContext
Duration adds a duration field to the logging context with the specified key and value.
func (*NopMutableLoggerContext) Err ¶
func (c *NopMutableLoggerContext) Err(string, error) MutableLoggerContext
Err adds an error field to the logger context and returns the same context for chaining.
func (*NopMutableLoggerContext) Float64 ¶
func (c *NopMutableLoggerContext) Float64(string, float64) MutableLoggerContext
Float64 adds a float64 key-value pair to the context without storing it and returns the receiver for chaining.
func (*NopMutableLoggerContext) Int ¶
func (c *NopMutableLoggerContext) Int(string, int) MutableLoggerContext
Int adds an integer field to the context and returns the updated MutableLoggerContext.
func (*NopMutableLoggerContext) Int64 ¶
func (c *NopMutableLoggerContext) Int64(string, int64) MutableLoggerContext
Int64 adds a key-value pair where the value is an int64 and returns the current MutableLoggerContext for chaining.
func (*NopMutableLoggerContext) Str ¶
func (c *NopMutableLoggerContext) Str(string, string) MutableLoggerContext
Str adds a string field with the given key and value to the logger context and returns the context for chaining.
type ObjectInfo ¶
type ObjectInfo struct {
LastModified time.Time
Metadata map[string]string
ContentType string
Size int64
}
ObjectInfo holds metadata about an object without its body, returned by Head.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option is a marker interface satisfied by both WorkerOption and AppOption. NewWorker and NewApp accept ...Option so callers can pass either type.
type Principal ¶
type Principal interface {
Subject() string
Scheme() string
CredentialID() string
Metadata() PrincipalMetadata
}
Principal represents an authenticated identity. Subject is the stable user identifier, Scheme identifies the authentication method (e.g. "jwt", "session", "apikey"), and CredentialID is the specific credential instance (session ID, JWT jti, API key ID).
func MustPrincipalFromContext ¶
MustPrincipalFromContext retrieves the Principal from the context and panics if no principal is present.
func PrincipalFromContext ¶
PrincipalFromContext retrieves the Principal from the context, or nil if no principal is present.
type PrincipalMetadata ¶
PrincipalMetadata provides read-only access to arbitrary key-value metadata attached to a Principal at construction time.
type PrincipalRevoker ¶
type PrincipalRevoker interface {
Revoke(ctx context.Context, principal Principal) error
RevokeAll(ctx context.Context, subject string) error
RevokeAllByScheme(ctx context.Context, subject, scheme string) error
}
PrincipalRevoker invalidates credentials associated with a Principal. Use Revoke to invalidate a single credential, RevokeAll to invalidate every credential for a subject, or RevokeAllByScheme to invalidate all credentials of a specific scheme (e.g. all sessions, all API keys) for a subject.
type ReadyProvider ¶
ReadyProvider aggregates readiness signals across all active services that implement ReadyReporter. The returned map keys are service names; a nil value indicates a ready service.
type ReadyReporter ¶
ReadyReporter is implemented by services that can report whether they are ready to accept traffic. Answers the question "should traffic be routed to me?" — distinct from health, since a service can be alive but not yet ready (warming caches, pending migrations, dependency briefly unavailable, draining during shutdown). Maps to a Kubernetes readinessProbe. A nil return means ready; a non-nil error describes why the service is not ready.
type RegisteredRoute ¶
RegisteredRoute is an exported snapshot of a registered route.
type RequestLoggerOption ¶
type RequestLoggerOption func(*RequestLoggerOptions)
RequestLoggerOption is a functional option for configuring RequestLogger.
func WithRequestLoggerAppendRequestID ¶
func WithRequestLoggerAppendRequestID(val bool) RequestLoggerOption
WithRequestLoggerAppendRequestID controls whether the request ID (from chi's RequestID middleware) is added to the logger's base fields. Defaults to true.
func WithRequestLoggerBuilder ¶
func WithRequestLoggerBuilder(fn func(Logger, *http.Request) Logger) RequestLoggerOption
WithRequestLoggerBuilder sets a function that customizes the logger used for each request. The builder receives the resolved Logger and the current request, and returns a (possibly wrapped or enriched) Logger. It is called after the request ID field is appended (if enabled). This can be used to add extra fields, swap the logger, or adjust log levels per request.
type RequestLoggerOptions ¶
type RequestLoggerOptions struct {
// contains filtered or unexported fields
}
RequestLoggerOptions configures the behavior of the RequestLogger middleware.
type Resolver ¶
type Resolver interface {
// contains filtered or unexported methods
}
Resolver is implemented by ServiceContainer and Scope to provide dependency resolution. The unexported method restricts implementation to this package.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router is a smart router that wraps Chi and tracks route and middleware ownership by service. MiddlewareByName middleware is resolved from an internal registry at registration time. The base server uses RemoveByModule during kill-switch to replace a closed service's routes with 503 handlers and remove its middleware.
Top-level routers created via NewRouter() start unsealed: Use, Handle, Group, and Route calls are deferred until Seal() is called. This lets services register middleware and routes in any order during Init(). Seal() flushes all pending middleware first (via chi.Use), then replays pending route operations — guaranteeing middleware-before-routes ordering that Chi requires.
Sub-routers (created inside Group/Route callbacks) are always sealed so their calls pass through to Chi immediately.
Concurrency model: once sealed, the live chi tree is immutable. ServeHTTP reads it lock-free via an atomic pointer (served). Runtime mutators (RemoveByModule, and Handle/Route/Group/Use via RestartService) never touch the tree in flight — they rebuild a fresh chi tree under r.mu by replaying the recorded registrations and atomically swap it in. In-flight requests keep serving the previous tree, which is never written after publication.
func NewRouter ¶
func NewRouter() *Router
NewRouter creates a Router backed by Chi with an empty middleware registry. The router starts unsealed — Use/Handle/Group/Route calls are deferred until Seal() is called.
func (*Router) Group ¶
Group creates an inline route group. The callback receives a sub-Router that shares the parent's middleware registry and route tracking. When the router is unsealed, the group is deferred until Seal().
func (*Router) Handle ¶
func (r *Router) Handle(service, method, path string, handler any, middleware ...Middleware)
Handle registers a route and tracks ownership. The handler can be:
- http.HandlerFunc or func(http.ResponseWriter, *http.Request) — passed through directly
- A DI-aware function: func(gas.Context, Dep1, Dep2, ...) error — dependencies are auto-resolved from the per-request scope at call time
Middleware is resolved from the internal registry (for MiddlewareByName) or used directly (for MiddlewareFunc) and applied in order (outermost first). Panics if a named middleware is not registered or if a DI-aware handler has an invalid signature. When the router is unsealed, the registration is deferred until Seal().
func (*Router) Mux ¶
Mux returns the underlying Chi router so the base server can add global middleware, mount sub-routers, or pass it to http.Server.
This returns the most recently built tree. Mutating it directly bypasses the router's synchronization and is only safe before serving begins.
func (*Router) NamedMiddleware ¶
NamedMiddleware returns a snapshot of the named middleware registry as a map of middleware name to owning service.
func (*Router) NotFound ¶
NotFound registers a custom not-found handler for the router, associated with the specified service. The handler can be http.HandlerFunc or a DI-aware function (same rules as Handle). Panics if a not found handler is already registered by another service.
func (*Router) Register ¶
Register adds a named middleware to the internal registry and tracks which service owns it.
func (*Router) RemoveByModule ¶
RemoveByModule removes all routes and middleware registered by the given service. Routes are replaced with 503 Service Unavailable handlers.
The teardown is applied by rebuilding a fresh routing tree and swapping it in atomically, so requests in flight on the old tree are never disrupted.
func (*Router) Route ¶
Route creates a pattern-scoped route group. The callback receives a sub-Router that shares the parent's middleware registry and route tracking. When the router is unsealed, the route is deferred until Seal().
Calling Route with the same pattern more than once on the same parent is allowed: subsequent calls attach to the sub-mux created by the first call instead of panicking. Each call's body runs inside its own chi.Group, so middleware added via Use() inside a given block only applies to handlers registered in that block.
func (*Router) Routes ¶
func (r *Router) Routes() map[string][]RegisteredRoute
Routes returns a snapshot of all explicitly registered routes grouped by service. Implicit HEAD routes (auto-registered alongside GET) are excluded.
func (*Router) Seal ¶
func (r *Router) Seal()
Seal builds the routing tree from the deferred middleware and route registrations and publishes it. Middleware is applied first (via chi.Use), then route operations are replayed in order. After Seal, structural changes rebuild the tree and swap it in atomically. Seal is idempotent — calling it on an already-sealed router is a no-op.
func (*Router) ServeHTTP ¶
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
ServeHTTP implements http.Handler, delegating to the published Chi tree. The tree is loaded atomically with no lock, so serving never contends with runtime route mutations.
func (*Router) SetErrorHandler ¶
func (r *Router) SetErrorHandler(h ErrorHandler)
SetErrorHandler configures the function that converts DI-aware handler errors into HTTP responses. Must be called before Handle() registrations.
func (*Router) Use ¶
func (r *Router) Use(middleware ...Middleware)
Use applies middleware to the router. Each Middleware is resolved (by name from the registry or used directly) and applied via chi's Use. Panics if a named middleware is not registered. When the router is unsealed, middleware is queued and applied during Seal().
func (*Router) UseMiddlewareByName ¶
UseMiddlewareByName applies a middleware to the router by resolving it from the registry using its name. Panics if the middleware is not registered.
type Rows ¶
Rows represents the result set of a query. Mirrors the standard database/sql Rows interface so implementations can wrap it directly.
type Scope ¶
type Scope struct {
// contains filtered or unexported fields
}
Scope is a resolution context for scoped service lifetimes.
func RequestScope ¶
RequestScope returns the per-request Scope from the request context. Panics if called outside the scope middleware (i.e. before InitServices installs it, or on a non-App-managed handler).
type SecurityHeadersOption ¶
type SecurityHeadersOption func(*SecurityHeadersOptions)
SecurityHeadersOption is a functional option for configuring SecurityHeaders.
func WithSecurityHeadersContentSecurityPolicy ¶
func WithSecurityHeadersContentSecurityPolicy(val string) SecurityHeadersOption
WithSecurityHeadersContentSecurityPolicy sets the Content-Security-Policy header value. Pass an empty string to disable this header. No default is applied, since CSP values are highly application-specific.
func WithSecurityHeadersContentTypeOptions ¶
func WithSecurityHeadersContentTypeOptions(val string) SecurityHeadersOption
WithSecurityHeadersContentTypeOptions sets the X-Content-Type-Options header value. Pass an empty string to disable this header. Default: "nosniff".
func WithSecurityHeadersCrossOriginOpenerPolicy ¶
func WithSecurityHeadersCrossOriginOpenerPolicy(val string) SecurityHeadersOption
WithSecurityHeadersCrossOriginOpenerPolicy sets the Cross-Origin-Opener-Policy header value. Pass an empty string to disable this header. No default is applied.
func WithSecurityHeadersCrossOriginResourcePolicy ¶
func WithSecurityHeadersCrossOriginResourcePolicy(val string) SecurityHeadersOption
WithSecurityHeadersCrossOriginResourcePolicy sets the Cross-Origin-Resource-Policy header value. Pass an empty string to disable this header. No default is applied.
func WithSecurityHeadersFrameOptions ¶
func WithSecurityHeadersFrameOptions(val string) SecurityHeadersOption
WithSecurityHeadersFrameOptions sets the X-Frame-Options header value. Pass an empty string to disable this header. Default: "DENY".
func WithSecurityHeadersPermissionsPolicy ¶
func WithSecurityHeadersPermissionsPolicy(val string) SecurityHeadersOption
WithSecurityHeadersPermissionsPolicy sets the Permissions-Policy header value. Pass an empty string to disable this header. Default: "camera=(), microphone=(), geolocation=()".
func WithSecurityHeadersReferrerPolicy ¶
func WithSecurityHeadersReferrerPolicy(val string) SecurityHeadersOption
WithSecurityHeadersReferrerPolicy sets the Referrer-Policy header value. Pass an empty string to disable this header. Default: "strict-origin-when-cross-origin".
func WithSecurityHeadersStrictTransportSecurity ¶
func WithSecurityHeadersStrictTransportSecurity(val string) SecurityHeadersOption
WithSecurityHeadersStrictTransportSecurity sets the Strict-Transport-Security (HSTS) header value. Pass an empty string to disable this header. No default is applied, since HSTS should only be enabled once the site is fully served over HTTPS.
type SecurityHeadersOptions ¶
type SecurityHeadersOptions struct {
// contains filtered or unexported fields
}
SecurityHeadersOptions configures which security headers are set by the SecurityHeaders middleware.
type ServerSettings ¶
type ServerSettings struct {
// Host specifies the hostname or IP address where the server will be hosted.
Host string
// Port is the port number on which the server listens for incoming requests.
Port int
// ReadTimeout is the maximum duration for reading the entire request.
ReadTimeout time.Duration
// WriteTimeout is the maximum duration before timing out writes of the response.
WriteTimeout time.Duration
// IdleTimeout is the maximum time to wait for the next request when keep-alives are enabled.
IdleTimeout time.Duration
// ShutdownTimeout is how long to wait for in-flight requests to complete
// during graceful shutdown.
ShutdownTimeout time.Duration
}
ServerSettings defines the configuration for a server, including host, port, timeouts, and graceful shutdown settings.
type Service ¶
type Service interface {
// Name returns the unique identifier for this service (e.g., "gas-auth").
Name() string
// Init initializes the service. Called automatically by the DI container
// after construction. Services register routes, middleware, migrations,
// and event subscriptions here.
Init() error
// Close gracefully shuts down the service. Called at App shutdown
// (singletons) or when a Scope is closed (scoped services).
Close() error
}
Service is the core interface for lifecycle-managed services. Any type registered with the DI container that implements this interface will have Init() called after construction and Close() called at shutdown (singletons) or scope end (scoped). Transient services cannot implement this interface — registration will be rejected.
type ServiceContainer ¶
type ServiceContainer struct {
// contains filtered or unexported fields
}
ServiceContainer is a dependency injection container that manages service registration, construction, and lifetime-scoped resolution.
func NewServiceContainer ¶
func NewServiceContainer() *ServiceContainer
NewServiceContainer creates a new ServiceContainer.
func (*ServiceContainer) BuildAll ¶
func (c *ServiceContainer) BuildAll() error
BuildAll eagerly resolves all singleton services in dependency order. Transient and scoped services are validated but not constructed.
func (*ServiceContainer) CanResolve ¶
func (c *ServiceContainer) CanResolve(t reflect.Type) bool
CanResolve reports whether the container has an instance or registration that can satisfy the given type (including interface matching).
func (*ServiceContainer) EachInstance ¶
func (c *ServiceContainer) EachInstance(fn func(reflect.Value))
EachInstance iterates all built singleton instances (including pre-registered ones).
func (*ServiceContainer) NewScope ¶
func (c *ServiceContainer) NewScope() *Scope
NewScope creates a scoped resolution context. Scoped services resolved within this scope share instances; singletons delegate to the container.
type ServiceLifetime ¶
type ServiceLifetime uint8
ServiceLifetime controls how a service instance is created and cached.
const ( // ServiceLifetimeSingleton services are created once and shared across all consumers. ServiceLifetimeSingleton ServiceLifetime = iota // ServiceLifetimeScoped services are created once per Scope. ServiceLifetimeScoped // ServiceLifetimeTransient services are created fresh on every resolution. ServiceLifetimeTransient )
func (ServiceLifetime) String ¶
func (l ServiceLifetime) String() string
type StorageObject ¶
type StorageObject struct {
Body io.ReadCloser
Metadata map[string]string
ContentType string
Size int64
}
StorageObject holds the response from a Download call, including the body and any metadata the backend provides (content type, size, etc.).
type StorageOption ¶
type StorageOption func(*storageOptions)
StorageOption configures a storage operation.
func InBucket ¶
func InBucket(name string) StorageOption
InBucket overrides the default bucket for a single operation.
func WithContentType ¶
func WithContentType(ct string) StorageOption
WithContentType sets the content type for an Upload.
func WithMetadata ¶
func WithMetadata(m map[string]string) StorageOption
WithMetadata attaches provider-specific key-value metadata to an Upload.
type StorageProvider ¶
type StorageProvider interface {
Upload(ctx context.Context, key string, data io.Reader, opts ...StorageOption) error
Download(ctx context.Context, key string, opts ...StorageOption) (*StorageObject, error)
Delete(ctx context.Context, key string, opts ...StorageOption) error
Head(ctx context.Context, key string, opts ...StorageOption) (*ObjectInfo, error)
PresignDownloadURL(ctx context.Context, key string, expires time.Duration, opts ...StorageOption) (string, error)
PresignUploadURL(ctx context.Context, key string, expires time.Duration, opts ...StorageOption) (string, error)
}
StorageProvider abstracts file storage (S3, DO Spaces, local filesystem, etc.).
type SystemAllServicesInitializedPayload ¶
type SystemAllServicesInitializedPayload struct{}
SystemAllServicesInitializedPayload is an empty payload for the all-services-initialized event.
type SystemServerShuttingDownPayload ¶
type SystemServerShuttingDownPayload struct{}
SystemServerShuttingDownPayload is an empty payload for the server-shutting-down event.
type SystemServiceClosedPayload ¶
type SystemServiceClosedPayload struct {
ServiceName string
}
SystemServiceClosedPayload carries the name of the closed service.
type SystemServiceInitializedPayload ¶
type SystemServiceInitializedPayload struct {
ServiceName string
}
SystemServiceInitializedPayload carries the name of the initialized service.
type SystemShuttingDownPayload ¶
type SystemShuttingDownPayload struct{}
SystemShuttingDownPayload is an empty payload for the shutting-down event.
type TemplateProvider ¶
type TemplateProvider interface {
// Get returns the raw template content by name.
Get(ctx context.Context, name string) ([]byte, error)
// List returns all available template names.
List(ctx context.Context) ([]string, error)
// Register adds or replaces a template by name and raw content.
Register(ctx context.Context, name string, content []byte) error
// RegisterFS walks an fs.FS and registers every template file found.
RegisterFS(ctx context.Context, fsys fs.FS) error
}
TemplateProvider abstracts template storage and retrieval. Implementations may be backed by a filesystem, database, memory, or any combination. Consumers such as UIProvider (HTML rendering) and EmailProvider (email templating) resolve raw template content through this interface.
type TemplatedEmail ¶
type TemplatedEmail struct {
SubjectTemplate string
TextTemplate string
HTMLTemplate string
Data any
Email
}
TemplatedEmail represents an email message where templates and data define subject, text, and HTML bodies.
type UIProvider ¶
type UIProvider interface {
Render(w http.ResponseWriter, name string, data any) error
RenderFragment(w http.ResponseWriter, name string, data any) error // renders without layout wrapper, useful for HTMX
RenderWithStatus(w http.ResponseWriter, status int, name string, data any) error
RegisterFuncs(funcs template.FuncMap)
}
UIProvider abstracts template rendering. Implemented by gas-ui or any other UI service. Template storage and retrieval is handled by TemplateProvider; UIProvider focuses on compilation and rendering.
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker manages service lifecycle, dependency injection, and the event bus without an HTTP server. Use it for non-HTTP environments such as AWS Lambda, background job processors, or CLI tools. For HTTP servers, use App which embeds Worker and adds routing, CSRF protection, and an HTTP listener.
func NewWorker ¶
NewWorker creates a Worker with the given options. Only WorkerOption values are applied; passing an AppOption panics.
func (*Worker) ActiveServices ¶
ActiveServices returns the names of all currently active services.
func (*Worker) ActiveServicesMap ¶
ActiveServicesMap returns a map of all currently active services. This is a test helper.
func (*Worker) CheckHealth ¶
CheckHealth runs CheckHealth concurrently on every active service that implements HealthReporter and returns a map of service name to result (nil if healthy). Services that do not implement HealthReporter are omitted.
func (*Worker) CheckReady ¶
CheckReady runs CheckReady concurrently on every active service that implements ReadyReporter and returns a map of service name to result (nil if ready). Services that do not implement ReadyReporter are omitted.
func (*Worker) CloseService ¶
CloseService performs the kill-switch sequence for a single service at runtime. Infrastructure is cleaned up first so that even if Close() panics or fails, routes and subscriptions are already removed.
func (*Worker) ConfigProvider ¶
func (w *Worker) ConfigProvider() ConfigProvider
ConfigProvider resolves the ConfigProvider from the DI container. Returns nil if no ConfigProvider is registered.
func (*Worker) InitServices ¶
InitServices builds all singletons via the DI container (which calls Init() on each Service automatically), then collects Service instances for runtime management.
func (*Worker) MigrationManager ¶
func (w *Worker) MigrationManager() MigrationManager
MigrationManager resolves the MigrationManager from the DI container. Returns nil if no MigrationManager is registered.
func (*Worker) RestartService ¶
RestartService re-initializes a previously closed service. The service must have been registered with the Worker at construction time and built during InitServices (i.e., it must be a singleton in serviceOrder).
func (*Worker) Run ¶
Run initializes services, runs migrations and ready hooks, then blocks until a SIGINT or SIGTERM signal is received before shutting down. For non-blocking lifecycle control, use Start and Shutdown directly.
func (*Worker) ServiceContainer ¶
func (w *Worker) ServiceContainer() *ServiceContainer
ServiceContainer returns the Worker's dependency injection container.
type WorkerOption ¶
type WorkerOption func(*Worker)
WorkerOption configures a Worker. It is the base option type for DI registration, ready hooks, and other non-HTTP concerns. Both NewWorker and NewApp accept WorkerOption values.
func WithReadyFunc ¶
func WithReadyFunc(fn func(*ServiceContainer) error) WorkerOption
WithReadyFunc registers a function that runs after all services are initialized and migrations are applied but before Run blocks or Start returns. Multiple funcs are called in registration order; any error aborts startup.
func WithScopedService ¶
func WithScopedService[T any](ctor any) WorkerOption
WithScopedService registers a service constructor with a scoped lifetime.
func WithService ¶
func WithService[T any](ctor any, lifetime ServiceLifetime) WorkerOption
WithService registers a constructor-based service with the given lifetime.
func WithServiceInstance ¶
func WithServiceInstance[T any](val T) WorkerOption
WithServiceInstance registers a pre-built service instance (singleton).
func WithSingletonService ¶
func WithSingletonService[T any](ctor any) WorkerOption
WithSingletonService registers a singleton service constructor.
func WithTransientService ¶
func WithTransientService[T any](ctor any) WorkerOption
WithTransientService registers a transient service constructor.