Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Add or change a rule

apimock set rule writes a rule to disk — no editor, no hand-authored TOML. Adds a new rule by default; pass --rule <n> to change an existing one instead. Either way it keeps the target file’s comments and formatting, and the config/rule-set files don’t need to exist yet — a fresh directory gets a minimal starting pair.

$ apimock set rule --path /orders/1 --status 200 \
    --json '{"id":1,"status":"shipped"}'
Applied:
  rule set: apimock-rule-set.toml (new rule)
  Added: rule set `./apimock-rule-set.toml` — rule set #1 (apimock-rule-set.toml): rules=1
  Updated: root config — apimock.toml: listener / log / service

That wrote:

[[rules]]

[rules.respond]
json = '{"id":1,"status":"shipped"}'
status = 200

[rules.when.request]
url_path = "/orders/1"

Where it writes, and how it decides add vs. change

--config/-c (default ./apimock.toml) and --rule-set (default ./apimock-rule-set.toml) name the two files; both are created if missing. Without --rule, the command adds a new rule — always appended, never inserted, since the address every set invocation uses to find a rule again (--rule-set path + 0-based index) has to stay stable across runs. With --rule <n>, it changes the rule already at that index instead — give it whatever flags actually differ; anything you don’t pass is left as it was.

$ apimock set rule --rule 0 --status 404 \
    --json '{"error":"not found"}' --dry-run
Would apply (--dry-run, nothing written):
  rule set: apimock-rule-set.toml, rule #0
  Updated: rule set `./apimock-rule-set.toml`, rule #0 — rule #1 in rule set #1

--dry-run previews the exact change and writes nothing, full stop — not even a bootstrap file, if the workspace didn’t exist yet. Drop it to actually apply.

--json, not --text, for a JSON body

--json <value> validates the value as JSON, writes it to respond.json, and it’s served as application/json. --text <value> writes respond.text and is always text/plain, even if the value happens to look like JSON — the two are mutually exclusive on purpose, so a body’s content-type is a declared choice, not a guess (see Rule-set schema). Get this wrong and the body is right but the header is not, exactly the kind of mismatch a strict client library rejects.

--format json

$ apimock set rule --path /orders/2 --status 201 \
    --json '{"id":2,"status":"pending"}' --format json
{
  "apimock": "5.19.0",
  "result": {
    "changed_files": [
      "./apimock-rule-set.toml"
    ],
    "changes": [
      {
        "kind": "Added",
        "summary": "added rule #2 in rule set #1",
        "target": "rule set `./apimock-rule-set.toml`, rule #1"
      }
    ],
    "dry_run": false,
    "requires_reload": true,
    "rule_set": "apimock-rule-set.toml"
  },
  "schema": 1
}

requires_reload tells a caller whether a running server needs a restart or reload to pick up the change — currently always true when anything changed, since apimock doesn’t yet reload on its own. A failure carries error.kind instead of result — see the response envelope.

Exit codes

0 applied (or, under --dry-run, would apply). 2 a bad invocation — an unknown or dangling flag, a target outside the confined directory — writes nothing at all, verified by asserting file contents unchanged rather than just reading the exit code. 1 the rule was loaded and addressed successfully but the save itself failed (a conflicting external edit, or an I/O error). Full flag list and every exit code on the CLI reference.

A worked, verified example — crates/apimock/examples/agent-bootstrap/ — walks through bootstrapping a workspace from nothing with set, checking it with get, and validating it, in the order an agent would actually run them.