API Faker is a lightweight Rust application that serves HTTP endpoints from a JSON configuration file. It is ideal for frontend or integration work whenever the real backend is still under construction.
- Arbitrary HTTP methods (GET, POST, PUT, PATCH, DELETE, …)
- Fully customizable status codes, headers, JSON bodies, and text bodies
- Routes can react to specific query parameters, including dedicated variants for different values
- Optional artificial delays (
delay_ms) for simulating loading states - Built-in health check at
GET /__healthand a complete route overview atGET /__routes - Error variants triggered via
?__error=nameor thex-api-faker-error: nameheader - Auto-generated OpenAPI document at
GET /__openapi.jsonplus an embedded Swagger UI atGET /__swagger - Permissive CORS configuration so local browsers can call the mock API without extra setup
- Host and port can be configured via CLI flags or directly inside the JSON file
- Request and response flags help you toggle variants and label responses without touching headers manually
- Built-in placeholder responses for
/robots.txtand/favicon.icokeep browser requests from cluttering the logs
The configuration lives in a JSON file (default: mock_endpoints.json). Example:
{
"server": {
"host": "0.0.0.0",
"port": 8080
},
"response_flags": ["example-env"],
"routes": [
{
"method": "GET",
"path": "/users",
"description": "Returns a list of demo users.",
"status": 200,
"response_flags": ["users-base"],
"body": {
"users": [
{ "id": 1, "name": "Ada" },
{ "id": 2, "name": "Linus" }
]
},
"variants": [
{
"description": "Filtered list when ?team=platform&active=true",
"query": {
"team": "platform",
"active": "true"
},
"response_flags": ["users-filtered"],
"body": {
"users": [
{ "id": 42, "name": "Grace" }
]
}
},
{
"description": "Empty list for ?team=support",
"query": {
"team": "support"
},
"request_flags": ["beta-list"],
"response_flags": ["users-beta"],
"body": {
"users": []
}
}
],
"error_variants": [
{
"name": "users-timeout",
"description": "Force a temporary outage via ?__error=users-timeout or header x-api-faker-error",
"status": 503,
"delay_ms": 1500,
"text_body": "upstream dependency unavailable"
}
]
}
]
}The optional server block controls which interface and port the mock server binds to:
| Field | Type | Description |
|---|---|---|
host |
String | Hostname or IP address, e.g., 127.0.0.1 or 0.0.0.0 |
port |
Number | TCP port (for example 8080) |
CLI flags (--host, -p/--port) always win. If you omit them, API Faker reads the values from the configuration file and ultimately falls back to 127.0.0.1:8080.
| Field | Type | Description |
|---|---|---|
method |
String | HTTP method (e.g., GET, POST, …) |
path |
String | Path segment that must match exactly |
status |
Number (optional) | HTTP status code (default 200) |
headers |
Object (optional) | Additional headers (name → value) |
body |
JSON (optional) | Arbitrary JSON response body |
text_body |
String (optional) | Plain-text response body |
query |
Object (optional) | Required query parameters |
request_flags |
Array (optional) | Flags the request must include (__flags parameter or header) |
response_flags |
Array (optional) | Flags automatically added to the x-api-faker-flags response header |
delay_ms |
Number (optional) | Artificial delay in milliseconds before sending the response |
variants |
Array (optional) | Variant list with overrides |
error_variants |
Array (optional) | Named error variants triggered via __error or header |
description |
String (optional) | Free-form description that also appears in GET /__routes |
Each variant can override the same fields (all optional). Non-specified values fall back to the base route.
Flags can be configured globally (response_flags at the root), per route, and per variant or error variant.
- Request flags determine whether a route or variant matches. A request can send flags via the
__flagsquery parameter (repeat it or comma-separate values) or via thex-api-faker-flagsheader. Every expected flag must be present. - Response flags are automatically appended to the
x-api-faker-flagsheader of the response. Values from global configuration, the route, and the current variant are merged (duplicates removed, order preserved).
This makes it easy to simulate feature toggles: send x-api-faker-flags: beta-users, return a different payload, and expose the active flags in the response headers.
error_variants let you simulate failure scenarios without altering query parameters. Each error variant needs a unique name and can optionally override the same fields as the base route (headers, body, text_body, status, delay_ms, description).
Trigger options:
-
Query parameter
?__error=<name> -
HTTP header
x-api-faker-error: <name>When the name matches, the error variant takes precedence over every other variant. The
GET /__routesendpoint lists each error trigger so you can see how to activate it.
- Rust 1.84+ (Edition 2024)
cargo run -- --config mock_endpoints.json --host 0.0.0.0 --port 8080All configured endpoints will then be available under http://host:port.
| Flag / Env | Description |
|---|---|
--config, API_FAKER_CONFIG |
Path to the JSON file with your routes (defaults to mock_endpoints.json). |
--host, API_FAKER_HOST |
Override the bind host (127.0.0.1 fallback). |
-p/--port, API_FAKER_PORT |
Preferred port (8080 fallback). If the port is occupied, API Faker auto-increments until it succeeds. |
--port-max, API_FAKER_PORT_MAX |
Highest port that the fallback logic may probe (default 65535). |
--log-level, API_FAKER_LOG |
Override tracing verbosity for both API Faker and Axum (error, warn, info, debug, trace). |
--dry-run |
Validate the configuration file and exit without binding a socket. |
Example: cargo run -- --config qa.json --host 0.0.0.0 --port 5000 --port-max 5100 --log-level debug will bind to the first free port in [5000, 5100] and emit verbose diagnostics. Pair --dry-run with CI to ensure configuration changes stay valid without spinning up the server.
- Copy
mock_endpoints.example.jsontomock_endpoints.jsonand adjust the routes. - Start the server with
cargo run(default config) or point to a different file viacargo run -- --config my_routes.json.
GET /__openapi.jsonalways returns the generated OpenAPI 3.1 document (including thex-api-fakervendor extension with variants/errors/flags).GET /__swaggerserves an embedded Swagger UI that automatically points to that document.- Both endpoints refresh instantly whenever you restart the server with a new JSON configuration.
| Workflow | File | Trigger | Purpose |
|---|---|---|---|
| Tests | .github/workflows/test.yml |
push / pull_request on main |
Runs cargo fmt --check, cargo clippy -D warnings, and cargo test. Uses dtolnay/rust-toolchain@stable plus Swatinem/rust-cache@v2. |
| Build | .github/workflows/build.yml |
push on main, workflow_dispatch |
Produces a release binary (cargo build --release --locked) for Linux, packages it as api-faker-linux-x86_64.tar.gz, and uploads it as an artifact. |
| Release | .github/workflows/release.yml |
Tags v*, workflow_dispatch |
Builds release artifacts for Linux, macOS, and Windows, uploads them, and publishes via softprops/action-gh-release with auto-generated notes. |
All workflows store their logs as artifacts and tap into the GitHub Actions cache for faster follow-up runs.
-
You can define multiple routes with the same path as long as the method differs.
-
Duplicate method+path combinations overwrite the previous route; a warning is logged.
-
GET /__routesquickly shows which mocks are currently active, including query expectations, flags, and error triggers.Notes:
- Each route may provide either
bodyortext_body. When serving text, the defaultContent-Typeistext/plain; charset=utf-8unless you override it. - When multiple routes share a path, the ones with matching
queryconstraints are evaluated first before falling back to a generic route. - Within a route,
variantsare checked for matching query parameters and request flags; if none apply, the server falls back to the base route.
- Each route may provide either