Documentation
¶
Index ¶
- Constants
- Variables
- func ExtractPathValues(requestPath, pattern string) map[string]string
- type AppConfig
- type AppHistoryConfig
- type AppReplayConfig
- type BasicAuthConfig
- type BehaviorConfig
- type BodyMatchCondition
- type BodyMatchConfig
- type CacheConfig
- type EditorConfig
- type EndpointConfig
- type HTTPStatusConfig
- type HTTPStatusMatchConfig
- type HandlerConfig
- type HistoryConfig
- type KeyValue
- type OptionalProperties
- type Paths
- type RedisConfig
- type ReplayConfig
- type ReplayEndpoint
- type ReplayMatch
- type ServiceConfig
- func (s *ServiceConfig) GetEndpointConfig(requestPath, method string) *EndpointConfig
- func (s *ServiceConfig) GetUpstream(requestPath, method string) *UpstreamConfig
- func (s *ServiceConfig) HistoryEnabled() bool
- func (s *ServiceConfig) OverwriteWith(other *ServiceConfig) *ServiceConfig
- func (s *ServiceConfig) ReplayEnabled() bool
- func (s *ServiceConfig) WithDefaults() *ServiceConfig
- type SpecOptions
- type StorageConfig
- type StorageType
- type UpstreamConfig
- type ValidateConfig
Constants ¶
const ( DefaultHistoryURL = "/.history" DefaultHistoryDuration = 60 * time.Minute DefaultReplayURL = "/.replay" DefaultReplayDuration = 24 * time.Hour )
const (
DefaultUpstreamTimeout = 5 * time.Second
)
DefaultUpstreamTimeout defaults.
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 ¶
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 ¶
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 ¶
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 ¶
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 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"`
}
type HTTPStatusMatchConfig ¶
type HTTPStatusMatchConfig []HTTPStatusConfig
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 OptionalProperties ¶
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.
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).