config

package
v2.8.11 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultHistoryURL      = "/.history"
	DefaultHistoryDuration = 60 * time.Minute

	DefaultReplayURL      = "/.replay"
	DefaultReplayDuration = 24 * time.Hour
)
View Source
const (
	DefaultUpstreamTimeout = 5 * time.Second
)

DefaultUpstreamTimeout defaults.

View Source
const DefaultValidationTimeout = 1 * time.Second

DefaultValidationTimeout bounds a single validate call when the service config doesn't set its own. Surfaced so middleware and integration tests share a single source of truth instead of two drifting consts.

Variables

View Source
var DefaultFailOnStatus = HTTPStatusMatchConfig{
	{Range: "400-499", Except: []int{401, 403}},
}

DefaultFailOnStatus is the default fail-on config applied when FailOn is nil. Most 4xx errors indicate client-side problems that the generator cannot fix. 401/403 are excluded because they typically indicate missing/invalid credentials in the proxy setup, not a real client error.

Functions

func ExtractPathValues

func ExtractPathValues(requestPath, pattern string) map[string]string

ExtractPathValues aligns segments of a request path against a pattern and returns a map of path variable names to their actual values. Returns nil if paths don't align.

Types

type AppConfig

type AppConfig struct {
	Title       string `yaml:"title" env:"APP_TITLE"`
	Port        int    `yaml:"port" env:"APP_PORT"`
	BaseURL     string `yaml:"baseURL" env:"APP_BASE_URL"`
	InternalURL string `yaml:"internalURL" env:"APP_INTERNAL_URL"`
	HomeURL     string `yaml:"homeURL" env:"APP_HOME_URL"`
	ServiceURL  string `yaml:"serviceURL" env:"APP_SERVICE_URL"`

	// AssetsURL is the base URL for static UI assets (CSS, JS, images, icons).
	// Empty means assets are served with relative paths (default).
	AssetsURL string `yaml:"assetsURL" env:"APP_ASSETS_URL"`

	ContextAreaPrefix string            `yaml:"contextAreaPrefix"`
	DisableUI         bool              `yaml:"disableUI" env:"APP_DISABLE_UI"`
	DisableConfigUI   bool              `yaml:"disableConfigUI" env:"APP_DISABLE_CONFIG_UI"`
	Paths             Paths             `yaml:"-"`
	Editor            *EditorConfig     `yaml:"editor"`
	History           *AppHistoryConfig `yaml:"history"`
	Replay            *AppReplayConfig  `yaml:"replay"`
	Storage           *StorageConfig    `yaml:"storage"`
	BasicAuth         *BasicAuthConfig  `yaml:"basicAuth"`
	Extra             map[string]any    `yaml:"extra"`
}

AppConfig is the app configuration.

func NewAppConfigFromBytes

func NewAppConfigFromBytes(bts []byte, baseDir string) (*AppConfig, error)

NewAppConfigFromBytes creates an AppConfig from YAML bytes, filling missing values with defaults. Environment variables override YAML values when set (via `env` struct tags).

func NewDefaultAppConfig

func NewDefaultAppConfig(baseDir string) *AppConfig

NewDefaultAppConfig creates a new default app config in case the config file is missing, not found or any other error.

type AppHistoryConfig

type AppHistoryConfig struct {
	Enabled  *bool         `yaml:"enabled" env:"ROUTER_HISTORY_ENABLED"`
	URL      string        `yaml:"url"`
	Duration time.Duration `yaml:"duration" env:"ROUTER_HISTORY_DURATION"`
}

AppHistoryConfig configures request/response history at the application level. Duration is the default history-recording TTL; a service's history.duration overrides it. Enabled=false stops history recording for all services and hides the history URL; a service's history.enabled overrides.

func NewDefaultAppHistoryConfig

func NewDefaultAppHistoryConfig() *AppHistoryConfig

NewDefaultAppHistoryConfig creates the default history config.

type AppReplayConfig added in v2.7.0

type AppReplayConfig struct {
	Enabled  *bool         `yaml:"enabled" env:"ROUTER_REPLAY_ENABLED"`
	URL      string        `yaml:"url"`
	Duration time.Duration `yaml:"duration" env:"ROUTER_REPLAY_DURATION"`
}

AppReplayConfig configures replay recording and the replay explorer at the application level. Duration is the default replay-recording TTL; a service's replay.duration overrides it. Enabled=false stops replay recording and serving for all services and hides the explorer URL; a service's replay.enabled overrides.

func NewDefaultAppReplayConfig added in v2.7.0

func NewDefaultAppReplayConfig() *AppReplayConfig

NewDefaultAppReplayConfig creates the default replay config.

type BasicAuthConfig added in v2.7.3

type BasicAuthConfig struct {
	User         string `yaml:"user" env:"MOCKZILLA_BASIC_AUTH_USER"`
	Password     string `yaml:"password" env:"MOCKZILLA_BASIC_AUTH_PASSWORD"`
	PasswordHash string `yaml:"passwordHash" env:"MOCKZILLA_BASIC_AUTH_PASSWORD_HASH"`
}

BasicAuthConfig gates the API Explorer UI with HTTP Basic Auth. It is active only when User and a password (PasswordHash or Password) are set. PasswordHash is the control-plane path: the platform stamps a SHA-256 hash so plaintext never reaches the sim. Password is the self-host convenience and is compared directly. The hash wins when both are present.

type BehaviorConfig added in v2.7.0

type BehaviorConfig struct {
	Upstream  *UpstreamConfig          `yaml:"upstream,omitempty"`
	Latency   time.Duration            `yaml:"latency,omitempty"`
	Latencies map[string]time.Duration `yaml:"latencies,omitempty"`
	Errors    map[string]int           `yaml:"errors,omitempty"`
	// contains filtered or unexported fields
}

BehaviorConfig holds the response-behavior knobs shared by a service and its endpoints: upstream proxying, injected latency, and injected errors. It is embedded (inline) into ServiceConfig and EndpointConfig so the YAML keys stay flat (upstream, latency, latencies, errors) at both levels.

func (*BehaviorConfig) GetError added in v2.7.0

func (b *BehaviorConfig) GetError() int

GetError returns an error code sampled from the configured percentiles, or 0 when none are defined.

func (*BehaviorConfig) GetLatency added in v2.7.0

func (b *BehaviorConfig) GetLatency() time.Duration

GetLatency returns the percentile-sampled latency when latencies are configured, otherwise the flat Latency.

type BodyMatchCondition

type BodyMatchCondition struct {
	Path   string      `yaml:"path"`
	Equals interface{} `yaml:"equals"`
}

type BodyMatchConfig

type BodyMatchConfig struct {
	Default string               `yaml:"default"`
	Fail    []BodyMatchCondition `yaml:"fail"`
	Except  []BodyMatchCondition `yaml:"except"`
}

type CacheConfig

type CacheConfig struct {
	Requests bool `yaml:"requests"`
}

CacheConfig defines the cache configuration for a service. Requests is a flag whether to cache GET requests.

func NewCacheConfig

func NewCacheConfig() *CacheConfig

NewCacheConfig creates a new CacheConfig with default values.

type EditorConfig

type EditorConfig struct {
	Theme     string `yaml:"theme"`
	DarkTheme string `yaml:"darkTheme"`
	FontSize  int    `yaml:"fontSize"`
}

type EndpointConfig added in v2.3.2

type EndpointConfig struct {
	BehaviorConfig `yaml:",inline"`
}

EndpointConfig defines per-endpoint behavior overrides. When an endpoint matches, its config completely replaces (not merges with) the service-level latency/error settings; Upstream, when set, replaces the service-level Upstream for this endpoint only.

type HTTPStatusConfig

type HTTPStatusConfig struct {
	Exact  int              `yaml:"exact"`
	Range  string           `yaml:"range"`
	Except []int            `yaml:"except"`
	Body   *BodyMatchConfig `yaml:"body"`
}

func (*HTTPStatusConfig) Is

func (s *HTTPStatusConfig) Is(status int, body string) bool

type HTTPStatusMatchConfig

type HTTPStatusMatchConfig []HTTPStatusConfig

func (HTTPStatusMatchConfig) Is

func (ss HTTPStatusMatchConfig) Is(status int, body string) bool

type HandlerConfig

type HandlerConfig struct {
	SelfPrefix string `yaml:"self-prefix"`
}

HandlerConfig is a config for the handler. It is created from the service config. SelfPrefix is the prefix for helper routes outside OpenAPI spec:

for example, payload generation.

func NewHandlerConfig

func NewHandlerConfig(service *ServiceConfig) *HandlerConfig

NewHandlerConfig creates a new handler config from the service config.

type HistoryConfig

type HistoryConfig struct {
	Enabled     *bool         `yaml:"enabled,omitempty"`
	Duration    time.Duration `yaml:"duration,omitempty"`
	MaskHeaders []string      `yaml:"mask-headers,omitempty"`
}

HistoryConfig controls request/response history recording for a service.

Enabled toggles recording on or off (defaults to true when nil). Duration is how long entries are kept before expiring; it overrides the app-level history.duration, falling back to it when unset. MaskHeaders lists header names whose values should be masked before saving, showing only the last 4 characters (matched case-insensitively).

Example YAML:

history:
  enabled: true
  duration: 30m
  mask-headers:
    - Authorization
    - X-Api-Key

Shorthand to disable history entirely:

history:
  enabled: false

func NewHistoryConfig

func NewHistoryConfig() *HistoryConfig

NewHistoryConfig creates a HistoryConfig with defaults: enabled, common sensitive headers masked.

func (*HistoryConfig) UnmarshalYAML

func (h *HistoryConfig) UnmarshalYAML(unmarshal func(any) error) error

UnmarshalYAML supports both boolean shorthand and object forms:

history: false        # shorthand to disable
history:              # full form
  enabled: true
  mask-headers: [Authorization]

type KeyValue

type KeyValue[K, V any] struct {
	Key   K
	Value V
}

type OptionalProperties

type OptionalProperties struct {
	Min int `yaml:"min"`
	Max int `yaml:"max"`
}

OptionalProperties controls how many optional properties to keep in generated types. This helps reduce the size of generated code for schemas with many optional fields.

Min and Max specify the range of optional properties to keep:

  • If Min == Max, keeps exactly that many optional properties
  • If Min < Max, keeps a random number between Min and Max (inclusive)

When nil (not set in config), all optional properties are kept.

type Paths

type Paths struct {
	Base      string
	Docs      string
	Resources string
	Data      string
	OpenAPI   string
	Static    string
	Services  string
	UI        string
}

Paths is a struct that holds all the paths used by the application.

func NewPaths

func NewPaths(baseDir string) Paths

type RedisConfig

type RedisConfig struct {
	// host:port address. When Host is set via env, Address is built from Host:Port.
	Address  string `yaml:"address"`
	Host     string `yaml:"host" env:"REDIS_HOST"`
	Port     string `yaml:"port" env:"REDIS_PORT" envDefault:"6379"`
	Username string `yaml:"username" env:"REDIS_USERNAME"`
	Password string `yaml:"password" env:"REDIS_PASSWORD"`
	DB       int    `yaml:"db" env:"REDIS_DB"`
	TLS      bool   `yaml:"tls" env:"REDIS_TLS"`
}

RedisConfig configures Redis connection.

func (*RedisConfig) GetAddress

func (r *RedisConfig) GetAddress() string

GetAddress returns the Redis address. If Host is set, it takes precedence over Address.

type ReplayConfig

type ReplayConfig struct {
	// Enabled toggles replay recording and serving (defaults to true when nil).
	Enabled *bool `yaml:"enabled,omitempty"`

	// Duration is how long recordings are kept. Defaults to the app-level
	// replay.duration when unset.
	Duration time.Duration `yaml:"duration"`

	// UpstreamOnly when true only records responses from upstream services.
	UpstreamOnly bool `yaml:"upstream-only"`

	// AutoReplay when true activates replay for configured endpoints without requiring
	// the X-Mockzilla-Replay header. When false (default), the header must be present.
	AutoReplay bool `yaml:"auto-replay"`

	// Endpoints maps path patterns to their match configurations.
	// Two forms are supported:
	//
	//   With method (matches only that method):
	//     /pay:
	//       POST:
	//         match: [reference]
	//
	//   Without method (matches any request method):
	//     /pay:
	//       match: [reference]
	Endpoints map[string]map[string]*ReplayEndpoint `yaml:"endpoints"`
}

ReplayConfig defines the replay (VCR-like) configuration for recording and replaying API responses based on request body content.

Replay is activated either by the X-Mockzilla-Replay header or by setting AutoReplay to true. When a request comes in, specified fields are extracted from the request body, a content-addressed key is built, and a stored recording is returned if one exists. If no recording exists, the response from downstream is captured and stored.

Example YAML:

replay:
  duration: 24h
  auto-replay: true
  upstream-only: false
  endpoints:
    /foo/{f-id}/bar/{b-id}:
      POST:
        match:
          body:
            - data.name
            - data.address.zip

func (*ReplayConfig) GetEndpoint

func (rc *ReplayConfig) GetEndpoint(requestPath, method string) (string, *ReplayEndpoint)

GetEndpoint finds the matching endpoint config for a request path and method. Returns the pattern path (for key building) and the endpoint config.

Three config forms are supported:

  • Path only ("/pay:") - matches any method, no match fields
  • Path + method ("/pay: POST:") - matches that method, no match fields
  • Path + method + match ("/pay: POST: match: [...]") - full config

Returns "", nil if no match is found.

type ReplayEndpoint

type ReplayEndpoint struct {
	// Match specifies which request fields form the replay key.
	Match *ReplayMatch `yaml:"match"`
}

ReplayEndpoint defines the match configuration for a specific endpoint and HTTP method.

type ReplayMatch

type ReplayMatch struct {
	// Path fields are path variable names to include in the replay key.
	Path []string `yaml:"path"`

	// Body fields are extracted from the request body (JSON dotted paths or form-encoded flat keys).
	Body []string `yaml:"body"`

	// Query fields are extracted from the URL query string.
	Query []string `yaml:"query"`
}

ReplayMatch specifies where to extract match field values from.

func (*ReplayMatch) AllFields

func (rm *ReplayMatch) AllFields() []string

AllFields returns all match field names (path + body + query) for key building.

type ServiceConfig

type ServiceConfig struct {
	BehaviorConfig `yaml:",inline"`

	Name        string                                `yaml:"name,omitempty"`
	Endpoints   map[string]map[string]*EndpointConfig `yaml:"endpoints,omitempty"`
	Cache       *CacheConfig                          `yaml:"cache,omitempty"`
	Replay      *ReplayConfig                         `yaml:"replay,omitempty"`
	History     *HistoryConfig                        `yaml:"history,omitempty"`
	Mount       string                                `yaml:"mount,omitempty"`
	SpecOptions *SpecOptions                          `yaml:"spec,omitempty"`
	Validate    *ValidateConfig                       `yaml:"validate,omitempty"`
	Extra       map[string]any                        `yaml:"extra,omitempty"`
}

ServiceConfig defines the configuration for a service. BehaviorConfig (inlined) carries the response-behavior knobs (upstream, latency, latencies, errors) shared with EndpointConfig. Name is the optional name of the service. Cache is the cache configuration; Replay is the replay (VCR) configuration. Mount is the URL prefix at which the service mounts. May contain `/` to allow multi-segment prefixes (e.g. "pets/v2"). When empty, the service mounts at "/<Name>". SpecOptions allows OpenAPI spec simplifications for code generation. Validate is the validation configuration.

func NewServiceConfig

func NewServiceConfig() *ServiceConfig

NewServiceConfig creates a new ServiceConfig with default values.

func NewServiceConfigFromBytes

func NewServiceConfigFromBytes(bts []byte) (*ServiceConfig, error)

func (*ServiceConfig) GetEndpointConfig added in v2.3.2

func (s *ServiceConfig) GetEndpointConfig(requestPath, method string) *EndpointConfig

GetEndpointConfig finds the matching endpoint config for a request path and method. Returns nil if no match is found. When matched, the endpoint config completely overrides service-level latency/error settings.

func (*ServiceConfig) GetUpstream added in v2.6.7

func (s *ServiceConfig) GetUpstream(requestPath, method string) *UpstreamConfig

GetUpstream returns the effective upstream config for the given request path and method. An endpoint-level Upstream replaces the service-level Upstream when set; otherwise the service-level Upstream is returned.

func (*ServiceConfig) HistoryEnabled

func (s *ServiceConfig) HistoryEnabled() bool

HistoryEnabled returns whether request history recording is enabled. Defaults to true when not explicitly set.

func (*ServiceConfig) OverwriteWith

func (s *ServiceConfig) OverwriteWith(other *ServiceConfig) *ServiceConfig

OverwriteWith overwrites fields in s with non-nil/non-empty values from other. This is useful for merging configurations where other takes precedence.

func (*ServiceConfig) ReplayEnabled added in v2.7.1

func (s *ServiceConfig) ReplayEnabled() bool

ReplayEnabled returns whether replay recording and serving is enabled. Defaults to true when not explicitly set.

func (*ServiceConfig) WithDefaults

func (s *ServiceConfig) WithDefaults() *ServiceConfig

WithDefaults fills nil properties with default values from NewServiceConfig.

type SpecOptions

type SpecOptions struct {
	LazyLoad bool `yaml:"lazyLoad"`
	Simplify bool `yaml:"simplify"`

	// Compress embeds the spec gzipped instead of verbatim, shrinking the
	// binary at the cost of a generated setup/spec.gz that has to be committed
	// alongside the generated code, since //go:embed resolves at compile time.
	Compress           bool                `yaml:"compress"`
	OptionalProperties *OptionalProperties `yaml:"optional-properties"`
}

SpecOptions allows OpenAPI spec simplifications for code generation. These simplifications are particularly helpful for enormous schemas that would otherwise generate unwieldy code.

Simplifications include:

  • Removal of extra union elements (anyOf/oneOf/allOf)
  • Optionally limiting the number of optional properties kept

LazyLoad enables on-demand parsing of operations. When true, operations are parsed only when first accessed and cached for subsequent requests. This significantly speeds up server startup for large specs (e.g., Stripe with 500+ endpoints).

OptionalProperties is nil by default, meaning all optional properties are kept. Set it explicitly to limit the number of optional properties.

Example usage in YAML:

spec:
  lazyLoad: true    # Parse operations on-demand instead of at startup
  simplify: true
  optional-properties:
    min: 5        # Keep exactly 5 optional properties (when min == max)
    max: 5
    # OR
    min: 2        # Keep random number between 2-8 optional properties
    max: 8

func NewSpecOptions

func NewSpecOptions() *SpecOptions

type StorageConfig

type StorageConfig struct {
	Type         StorageType    `yaml:"type" env:"STORAGE_TYPE"`
	DriverConfig map[string]any `yaml:"-"`

	// Redis is kept for backward compatibility with env tags (REDIS_HOST, etc.).
	Redis *RedisConfig `yaml:"redis"`
}

StorageConfig configures shared storage for distributed features.

Each driver's options live under a YAML key matching the type name:

storage:
  type: redis
  redis:
    address: localhost:6379

DriverConfig is populated automatically from the matching section.

func (*StorageConfig) DriverOptions

func (c *StorageConfig) DriverOptions() map[string]any

DriverOptions returns the driver-specific config map. It prefers DriverConfig (extracted from the type-named YAML section). Falls back to converting the typed Redis config for backward compatibility.

type StorageType

type StorageType string

StorageType defines the type of storage backend.

const (
	// StorageTypeMemory is the default in-memory storage (per-instance).
	StorageTypeMemory StorageType = "memory"

	// StorageTypeRedis uses Redis for distributed storage.
	StorageTypeRedis StorageType = "redis"
)

type UpstreamConfig

type UpstreamConfig struct {
	URL     string            `yaml:"url"`
	Timeout time.Duration     `yaml:"timeout"`
	Headers map[string]string `yaml:"headers"`

	// FailOn defines which upstream HTTP status codes should be returned immediately
	// to the client without falling back to the generator.
	// nil (omitted): uses default (400-499 except 401, 403). Set to empty list (fail-on: []) to disable.
	FailOn *HTTPStatusMatchConfig `yaml:"fail-on"`

	// StickyTimeout enables server-side session affinity for upstream/generator routing.
	// When a client gets a generated (fallback) response, subsequent requests from the
	// same remote address skip upstream for this duration. 0 or omitted = disabled.
	StickyTimeout time.Duration `yaml:"sticky-timeout"`
}

type ValidateConfig added in v2.6.0

type ValidateConfig struct {
	Request  *bool `yaml:"request,omitempty"`
	Response *bool `yaml:"response,omitempty"`
	// Verbose keeps the validator's bulky ReferenceSchema and
	// ReferenceObject fields in the client-facing error payload. Default
	// (false) strips them so clients get a slim error with just the
	// actionable bits (reason, path, location, line/column). Tests and
	// debugging sessions set it true to see the full context.
	Verbose *bool `yaml:"verbose,omitempty"`
	// Timeout bounds a single request- or response-validation call.
	// The validator inlines the schema before checking the body, and
	// pathological specs (deeply self-referential allOf, mutually
	// recursive components, very large request bodies) trigger
	// exponential rendering that never returns within a request
	// lifetime. On timeout we skip validation for that request rather
	// than block the response. Default 1s; bump for specs with
	// legitimately large/complex bodies.
	Timeout *time.Duration `yaml:"timeout,omitempty"`
}

ValidateConfig toggles request and response validation against the OpenAPI schema. Both default to false (opt-in): building the validator is the dominant cold-start cost (hundreds of MB of heap and seconds of CPU on spec-heavy services like fordefi), and a mock that quietly responds to a malformed client request is rarely worse than one that 400s. Users who want strict validation set request and/or response to true explicitly. In codegen mode validation is wired into the generated code, so this struct is ignored there.

func (*ValidateConfig) RequestEnabled added in v2.6.0

func (v *ValidateConfig) RequestEnabled() bool

RequestEnabled reports whether request validation is enabled. Defaults to false.

func (*ValidateConfig) ResponseEnabled added in v2.6.0

func (v *ValidateConfig) ResponseEnabled() bool

ResponseEnabled reports whether response validation is enabled. Defaults to false.

func (*ValidateConfig) TimeoutOrDefault added in v2.6.0

func (v *ValidateConfig) TimeoutOrDefault() time.Duration

TimeoutOrDefault returns the configured timeout, falling back to DefaultValidationTimeout when unset or non-positive. Non-positive values are treated as unset so a typo can't accidentally disable the timeout safety net.

func (*ValidateConfig) VerboseEnabled added in v2.6.0

func (v *ValidateConfig) VerboseEnabled() bool

VerboseEnabled reports whether full validator context is kept in the response payload. Defaults to false (slim).

Jump to

Keyboard shortcuts

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