Advanced Behavior and Simulation
MockForge provides advanced behavior and simulation features that allow you to create realistic, stateful, and resilient API mocks. This guide covers record & playback, stateful behavior simulation, fault injection, latency simulation, and conditional proxying.
Table of Contents
- Record & Playback
- Stateful Behavior Simulation
- Per-Route Fault Injection
- Per-Route Latency Simulation
- Conditional Proxying
Record & Playback
The record & playback feature allows you to capture real API interactions and convert them into replayable stub mappings.
Quick Start
- Start recording the requests the server handles:
mockforge serve --spec api-spec.json --recorder --recorder-db ./mockforge-recordings.db
- Convert recordings to stub mappings:
# Convert a specific recording
mockforge recorder convert --recording-id abc123 --output fixtures/user-api.yaml
# Batch convert all recordings
mockforge recorder convert --input recordings.db --output fixtures/ --format yaml
Configuration
core:
recorder:
enabled: true
auto_convert: true
output_dir: "./fixtures/recorded"
format: "yaml"
filters:
min_status_code: 200
max_status_code: 299
exclude_paths:
- "/health"
- "/metrics"
API Usage
# Convert via API
curl -X POST http://localhost:9080/api/recorder/convert/abc123 \
-H "Content-Type: application/json" \
-d '{"format": "yaml"}'
Stateful Behavior Simulation
Stateful behavior simulation allows responses to change based on previous requests, using state machines to track resource state.
Basic Example
core:
stateful:
enabled: true
state_machines:
- name: "order_workflow"
initial_state: "pending"
states:
- name: "pending"
response:
status_code: 200
body_template: '{"order_id": "{{resource_id}}", "status": "pending"}'
- name: "processing"
response:
status_code: 200
body_template: '{"order_id": "{{resource_id}}", "status": "processing"}'
- name: "shipped"
response:
status_code: 200
body_template: '{"order_id": "{{resource_id}}", "status": "shipped"}'
resource_id_extract:
type: "path_param"
param: "order_id"
transitions:
- method: "POST"
path_pattern: "/api/orders"
from_state: "initial"
to_state: "pending"
- method: "PUT"
path_pattern: "/api/orders/{order_id}/process"
from_state: "pending"
to_state: "processing"
Resource ID Extraction
Extract resource IDs from various sources:
# From path parameter
resource_id_extract:
type: "path_param"
param: "order_id"
# From header
resource_id_extract:
type: "header"
name: "X-Resource-ID"
# From JSONPath in request body
resource_id_extract:
type: "json_path"
path: "$.order.id"
# Composite (tries multiple sources)
resource_id_extract:
type: "composite"
extractors:
- type: "path_param"
param: "order_id"
- type: "header"
name: "X-Order-ID"
Per-Route Fault Injection
Configure fault injection on specific routes with multiple fault types.
Configuration
core:
routes:
- path: "/api/payments/process"
method: "POST"
fault_injection:
enabled: true
probability: 0.05 # 5% chance
fault_types:
- type: "http_error"
status_code: 503
message: "Service unavailable"
- type: "timeout"
duration_ms: 5000
- type: "connection_error"
message: "Connection refused"
Fault Types
- HTTP Error: Return specific status codes
- Connection Error: Simulate connection failures (HTTP-503 by default; see below for TCP-level)
- Timeout: Real
tokio::sleep(timeout_ms)then504 Gateway Timeout - Partial Response: Truncate responses (chunked-aware: keeps Content-Length on non-chunked, drops the terminator on chunked)
- Payload Corruption: Corrupt response payloads
Per-Request Matchers (v0.3.125+)
By default, fault probabilities apply to every request. To gate fault injection
on properties of the incoming request — useful for targeting specific clients,
headers, body sizes, or Transfer-Encoding: chunked traffic without affecting
baseline traffic — add a request_matcher block:
fault_injection:
enabled: true
http_errors: [503]
http_error_probability: 0.5 # 50% of *matching* requests get 503
request_matcher:
source_ips:
- "10.0.0.0/8" # CIDR or bare IP
- "192.168.1.42"
headers:
- name: "x-test" # case-insensitive name
value: "yes" # omit `value` for presence-only
min_body_size_bytes: 1048576 # only requests with body >= 1 MB
max_body_size_bytes: 10485760 # AND <= 10 MB (omit either side)
chunked_only: true # only Transfer-Encoding: chunked
Semantics: AND across fields, OR within a list. Empty matcher matches every request. Applies to all five fault paths (HTTP errors, timeouts, partial responses, payload corruption, connection errors).
Connection Error Wire-Level Behavior (v0.3.125+)
The connection_error_kind knob picks what “connection error” means at the
TCP level:
| Kind | What clients see |
|---|---|
http_503 (default) | HTTP 503 on a healthy connection — application layer only |
tcp_reset | TCP RST sent at accept time. Clients see ECONNRESET. |
tcp_close | TCP FIN at accept time. Clients see EOF before any HTTP response. |
fault_injection:
enabled: true
connection_errors: true
connection_error_probability: 0.05
connection_error_kind: tcp_reset # http_503 | tcp_reset | tcp_close
The TCP-level kinds wrap the listener with a chaos accept loop, so the fault
is per-connection (every request that would have pipelined onto that socket
is affected). Auto-installed by mockforge serve when chaos is enabled and
the kind is not http_503. Plain HTTP only — TLS path doesn’t yet support
TCP-level injection.
For the full reference (every fault config field, hot-reload API, predefined scenarios), see the Chaos Engineering chapter.
Per-Route Latency Simulation
Simulate network latency with various distributions.
Configuration
core:
routes:
- path: "/api/search"
method: "GET"
latency:
enabled: true
probability: 0.8
distribution: "normal" # fixed, normal, exponential, uniform
mean_ms: 500.0
std_dev_ms: 100.0
jitter_percent: 15.0
Distributions
- Fixed: Constant delay with optional jitter
- Normal: Gaussian distribution (realistic for most APIs)
- Exponential: Exponential distribution (simulates network delays)
- Uniform: Random delay within a range
Conditional Proxying
Proxy requests conditionally based on request attributes using expressions.
Availability: conditional proxy rules are applied by the HTTP router when it is built with a
ProxyConfig, which today happens through the Rust SDK (MockServerBuilder::proxy(config)inmockforge-sdk).mockforge servedoes not read aproxy:section from the config file yet. The YAML below shows theProxyConfig/ProxyRulefield names.
Basic Examples
# ProxyConfig
enabled: true
rules:
# Proxy admin requests
- pattern: "/api/admin/*"
upstream_url: "https://admin-api.example.com"
condition: "$.user.role == 'admin'"
# Proxy authenticated requests
- pattern: "/api/protected/*"
upstream_url: "https://protected-api.example.com"
condition: "header[authorization] != ''"
# Proxy based on query parameter
- pattern: "/api/data/*"
upstream_url: "https://data-api.example.com"
condition: "query[env] == 'production'"
Condition Types
JSONPath Expressions
condition: "$.user.role == 'admin'"
condition: "$.order.amount > 1000"
Header Checks
condition: "header[authorization] != ''"
condition: "header[user-agent] == 'MobileApp/1.0'"
Query Parameters
condition: "query[env] == 'production'"
condition: "query[version] == 'v2'"
Logical Operators
# AND
condition: "AND(header[authorization] != '', $.user.role == 'admin')"
# OR
condition: "OR(query[env] == 'production', query[env] == 'staging')"
# NOT
condition: "NOT(query[env] == 'development')"
Priority Chain
MockForge processes requests through this priority chain:
- Replay - Check for recorded fixtures
- Stateful - Check for stateful response handling
- Route Chaos - Apply per-route fault injection and latency
- Global Fail - Apply global/tag-based failure injection
- Proxy - Check for conditional proxying
- Mock - Generate mock response from OpenAPI spec
- Record - Record request for future replay
Related Advanced Features
MockForge includes many additional advanced features that complement the basic advanced behavior:
- VBR Engine: Virtual database layer with automatic CRUD generation
- Temporal Simulation: Time travel and time-based data mutations
- Scenario State Machines: Visual flow editor for complex workflows
- MockAI: AI-powered intelligent response generation
- Chaos Lab: Interactive network condition simulation
- Reality Slider: Unified control for mock environment realism
For a complete overview, see Advanced Features.
Best Practices
- Start simple - Begin with basic configurations and add complexity gradually
- Test thoroughly - Verify state transitions and conditions work as expected
- Monitor performance - Latency injection can slow down tests
- Document conditions - Keep conditional logic well-documented
- Use version control - Track configuration changes over time
Examples
See the example configuration file for comprehensive examples of all features.
For more details, see the Advanced Behavior and Simulation documentation.