Documentation
¶
Index ¶
- Constants
- Variables
- func Configure(envPrefix string, cfgs ...Configurable) error
- func ContextWithCorrelationID(ctx context.Context, id string) context.Context
- func CorrelationIDFromContext(ctx context.Context) string
- func IsBadRequestError(err error) bool
- func IsBusinessError(err error) bool
- func IsForbiddenError(err error) bool
- func IsInternalError(err error) bool
- func IsNotFoundError(err error) bool
- func IsUnauthorizedError(err error) bool
- func NewLogger(config *LogConfig) *slog.Logger
- func NewViper(envPrefix string) (*viper.Viper, error)
- func SortableMSToTime(st string) time.Time
- func SortableToTime(st string) time.Time
- func TimeToSortable(t time.Time) string
- func TimeToSortableMS(t time.Time) string
- func TruncateToSecond(t time.Time) time.Time
- type Closer
- type ConfigLoader
- type Configurable
- type ConfigurableFunc
- type Error
- func GetError(err error) *Error
- func NewBadRequestError(subject, message string) *Error
- func NewBusinessError(subject, message string) *Error
- func NewError(errorType ErrorType, subject, message string) *Error
- func NewForbiddenError(subject, message string) *Error
- func NewInternalError(subject, message string) *Error
- func NewNotFoundError(subject, message string) *Error
- func NewUnauthorizedError(subject, message string) *Error
- func (e *Error) Error() string
- func (e *Error) Is(target error) bool
- func (e *Error) MarshalJSON() ([]byte, error)
- func (e *Error) Unwrap() error
- func (e *Error) WithCode(code int) *Error
- func (e *Error) WithInner(inner error) *Error
- func (e *Error) WithMessage(message string, params ...any) *Error
- func (e *Error) WithParams(keyvals ...any) *Error
- func (e *Error) WithSubject(subject string) *Error
- type ErrorResponse
- type ErrorType
- type FixedClock
- type HealthChecker
- type Initer
- type LogConfig
- type LogOutputConfig
- type PostConfigLoader
- type Starter
- type SystemClock
- type TimeProvider
Constants ¶
const CorrelationIDHeader = "X-Correlation-ID"
CorrelationIDHeader is the canonical header / message-attribute key for propagating a correlation (request) ID across HTTP and messaging layers.
Variables ¶
var ( ErrBadRequest = NewBadRequestError("General", "Bad Request") ErrNotFound = NewNotFoundError("General", "Not Found") ErrBusiness = NewBusinessError("General", "Business") ErrForbidden = NewForbiddenError("General", "Forbidden") ErrInternal = NewInternalError("General", "Internal") )
var Clock = SystemClock{}
Clock is a process-wide SystemClock kept for backward compatibility. Prefer injecting a TimeProvider (host.WithClock) over reaching for this global.
Functions ¶
func Configure ¶ added in v0.4.0
func Configure(envPrefix string, cfgs ...Configurable) error
Configure creates a single ConfigLoader and calls LoadConfig on each Configurable in order. Use NewConfigLoader when you need to reuse the same parsed config across multiple calls.
func ContextWithCorrelationID ¶ added in v0.7.0
ContextWithCorrelationID returns a copy of ctx carrying id.
func CorrelationIDFromContext ¶ added in v0.7.0
CorrelationIDFromContext returns the correlation ID stored in ctx, or "" if none was set.
func IsBadRequestError ¶
func IsBusinessError ¶
func IsForbiddenError ¶
func IsInternalError ¶
func IsNotFoundError ¶
func IsUnauthorizedError ¶
func NewLogger ¶
NewLogger constructs a *slog.Logger from LogConfig. Console output is always enabled unless config.Console.Enabled=false. A second file output is added when config.File.Enabled=true and config.File.Path is set. Each output has its own level and format, falling back to config.Level and config.Format.
func NewViper ¶ added in v0.4.0
NewViper builds the viper instance microjet uses to load configuration: it searches the standard config paths, reads config.toml plus an optional config.local.toml overlay, and binds APP_* environment overrides. It is exported so provider-specific modules (e.g. aws) can build their own config loading without core having to depend on them.
func SortableMSToTime ¶
func SortableToTime ¶
func TimeToSortable ¶
func TimeToSortableMS ¶
TimeToSortableMS formats t as a 17-digit lexicographically sortable string with millisecond precision: YYYYMMDDHHMMSSmmm. Go only recognizes fractional seconds when preceded by a separator, so we format with a dot and strip it.
Types ¶
type Closer ¶ added in v0.4.0
type Closer interface {
Close() error
}
Closer is implemented by services that need to release resources on shutdown. The host calls Close on each registered service that implements this interface (host.ServiceCloser takes precedence when present).
type ConfigLoader ¶ added in v0.4.0
type ConfigLoader struct {
// contains filtered or unexported fields
}
ConfigLoader wraps a viper instance and exposes config-loading operations to Configurable implementations without leaking the viper dependency.
func NewConfigLoader ¶ added in v0.4.0
func NewConfigLoader(envPrefix string) (*ConfigLoader, error)
NewConfigLoader creates a ConfigLoader backed by a freshly parsed viper instance. Use this to hold a single loader across multiple Configure calls (e.g. in App.configLoader) so the config file is only read once.
func (*ConfigLoader) Configure ¶ added in v0.4.0
func (l *ConfigLoader) Configure(cfgs ...Configurable) error
Configure calls LoadConfig on each Configurable in order using the shared viper instance. If a Configurable also implements PostConfigLoader, PostLoadConfig is called immediately after its LoadConfig succeeds.
func (*ConfigLoader) GetStringMap ¶ added in v0.4.0
func (l *ConfigLoader) GetStringMap(key string) map[string]any
GetStringMap returns all keys and their values under a config section. Sub-tables appear as map[string]any values, scalars as their native types.
func (*ConfigLoader) SetDefault ¶ added in v0.4.0
func (l *ConfigLoader) SetDefault(key string, value any)
SetDefault registers a default value for a config key. Configurables call this before UnmarshalKey so their defaults apply when no config file is present.
func (*ConfigLoader) UnmarshalKey ¶ added in v0.4.0
func (l *ConfigLoader) UnmarshalKey(section string, dest any) error
UnmarshalKey unmarshals the named config section into dest.
type Configurable ¶ added in v0.4.0
type Configurable interface {
LoadConfig(*ConfigLoader) error
}
Configurable is implemented by any type that can populate itself from a ConfigLoader. LoadAll calls LoadConfig on each registered value in order, passing the same parsed viper instance to all of them.
type ConfigurableFunc ¶ added in v0.4.0
type ConfigurableFunc func(*ConfigLoader) error
ConfigurableFunc is a function adapter for Configurable, analogous to http.HandlerFunc.
func (ConfigurableFunc) LoadConfig ¶ added in v0.4.0
func (f ConfigurableFunc) LoadConfig(l *ConfigLoader) error
type Error ¶
type Error struct {
Type ErrorType `json:"type"`
Subject string `json:"subject"`
Message string `json:"message"`
Params map[string]any `json:"params,omitempty"`
Code int `json:"code"`
Inner error `json:"-"`
}
func NewBadRequestError ¶
func NewBusinessError ¶
func NewForbiddenError ¶
func NewInternalError ¶
func NewNotFoundError ¶
func NewUnauthorizedError ¶
func (*Error) Is ¶
Is reports whether e matches target for errors.Is, letting a typed *Error be used as a sentinel by category. target matches when it is an *Error of the same Type; if target also sets a non-zero Code it must match, and if target sets a Subject other than the default "General" it must match too. This makes the package sentinels match any error of their category — errors.Is(err, ErrNotFound) is true for any NotFound error — while a custom sentinel carrying a Subject and/or Code matches more narrowly. Wrapped non-Error sentinels still match through Unwrap as usual.
func (*Error) MarshalJSON ¶
func (*Error) WithMessage ¶
WithMessage returns a copy of the error with the message replaced. Optional key-value pairs are merged into Params (same semantics as WithParams).
func (*Error) WithParams ¶
WithParams returns a copy of the error with additional key-value pairs merged into Params. Keys must be strings; non-string keys are silently skipped.
func (*Error) WithSubject ¶
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
Subject string `json:"subject"`
Message string `json:"message"`
Params map[string]any `json:"params,omitempty"`
Code int `json:"code"`
InnerError *string `json:"innerError,omitempty"`
}
ErrorResponse is the JSON body returned by the HTTP error middleware.
type ErrorType ¶
type ErrorType string
ErrorType identifies the category of an error and controls HTTP status mapping: BadRequest→400, Unauthorized→401, Forbidden→403, NotFound→404, Business→409, Internal→500.
func GetErrorType ¶
type FixedClock ¶
FixedClock is a TimeProvider that reports a preset time, for deterministic tests. It is not safe for concurrent mutation; set the time before use.
func NewFixedClock ¶
func NewFixedClock(t time.Time) *FixedClock
NewFixedClock returns a FixedClock pinned to t (normalized to UTC).
func (*FixedClock) Advance ¶
func (c *FixedClock) Advance(d time.Duration)
Advance moves the clock forward by d.
func (*FixedClock) Now ¶
func (c *FixedClock) Now() time.Time
func (*FixedClock) NowSortable ¶
func (c *FixedClock) NowSortable() string
func (*FixedClock) NowSortableMS ¶
func (c *FixedClock) NowSortableMS() string
func (*FixedClock) NowTS ¶
func (c *FixedClock) NowTS() int64
func (*FixedClock) Set ¶
func (c *FixedClock) Set(t time.Time)
Set replaces the time the clock reports.
type HealthChecker ¶ added in v0.4.0
HealthChecker is implemented by services that can report whether they are ready to serve traffic. The host's /readyz probe consults every registered service implementing it, so databases, cache, messaging, and any user service that implements this interface are covered without per-type wiring. Healthy returns nil when ready and a self-describing error otherwise.
type Initer ¶ added in v0.4.0
type Initer interface {
Init() error
}
Initer is implemented by services that need to perform initialization after their config is loaded but do not require host-level DI. The host calls Init on each registered service that implements this interface (host.ServiceIniter, which carries *App, takes precedence).
type LogConfig ¶
type LogConfig struct {
Level string `mapstructure:"level"`
Format string `mapstructure:"format"`
Console *LogOutputConfig `mapstructure:"console"`
File *LogOutputConfig `mapstructure:"file"`
}
LogConfig configures the logger. Console output is always enabled unless explicitly disabled via Console.Enabled=false. A file output is added when File.Enabled=true and File.Path is set. Each output can independently override the top-level Level and Format. Valid levels: debug, info, warn, error. Valid formats: text, json.
type LogOutputConfig ¶
type LogOutputConfig struct {
Enabled bool `mapstructure:"enabled"`
Level string `mapstructure:"level"` // overrides LogConfig.Level for this output
Format string `mapstructure:"format"` // overrides LogConfig.Format for this output
Path string `mapstructure:"path"` // file output only; parent dirs are created automatically
}
LogOutputConfig configures a single log output destination (console or file).
type PostConfigLoader ¶ added in v0.4.0
type PostConfigLoader interface {
PostLoadConfig() error
}
PostConfigLoader is an optional extension of Configurable. If a Configurable also implements PostConfigLoader, LoadAll calls PostLoadConfig immediately after LoadConfig succeeds, allowing validation or derived-field initialization.
type Starter ¶ added in v0.4.0
type Starter interface {
Start() error
}
Starter is implemented by services that begin active work (serving, listening) only after every service has finished Init. Splitting Start from Init gives the host a window between "resources acquired" and "serving" in which setup work (migrations, route registration) can run. The host calls Start on each registered service implementing this interface (host.ServiceStarter, which carries *App, takes precedence).
type SystemClock ¶
type SystemClock struct{}
SystemClock is a TimeProvider backed by the real wall clock, normalized to UTC.
func (SystemClock) Now ¶
func (SystemClock) Now() time.Time
Value receivers so both SystemClock{} and &SystemClock{} satisfy TimeProvider.
func (SystemClock) NowSortable ¶
func (c SystemClock) NowSortable() string
func (SystemClock) NowSortableMS ¶
func (c SystemClock) NowSortableMS() string
func (SystemClock) NowTS ¶
func (c SystemClock) NowTS() int64
type TimeProvider ¶
type TimeProvider interface {
Now() time.Time
NowTS() int64
NowSortable() string
NowSortableMS() string
}
TimeProvider supplies the current time. Inject it (e.g. via host.WithClock) so time-dependent code can be made deterministic in tests by swapping in a FixedClock instead of reaching for time.Now() directly.
var UTC TimeProvider = SystemClock{}
UTC is the default real-time clock, used when no clock is injected.