apimock 5.19.0

HTTP(S) mock server. Drop JSON files into a folder and your API immediately exists.
Documentation
# Validate config in CI

Two commands that check a config or a rule set without starting a
server - the right shape for a CI step or a pre-commit hook. This set
has no `curl` walkthrough; both commands are the thing being
demonstrated, and their exit code and output are what a CI job checks.

## `apimock validate`

Loads the whole workspace (root config + every rule set it references)
and reports diagnostics without binding a port.

```sh
$ cd crates/apimock/examples/validate-in-ci
$ apimock validate --config ./apimock.toml
Validation passed (2 rules across 1 rule set(s)).
$ echo $?
0
```

`--json` emits the diagnostics array instead (empty here, since
there's nothing to report). **Deprecated as of 5.19.0** — still works,
byte-identical, but now prints a one-line warning to stderr; `--format
json` (the [CLI reference](../../../../docs/src/reference/cli-reference.md#the-response-envelope---format-json))
is the replacement for new CI steps:

```sh
$ apimock validate --config ./apimock.toml --json
[]
Validation passed (2 rules across 1 rule set(s)).
```

Exit codes: `0` clean, `2` the config couldn't even be loaded. **Exit
`1` and `--strict` are documented but not reachable through this
command** — the load step above already rejects, identically, every
condition that would otherwise become a reported diagnostic, so a
problem fails validation by failing to *load* (exit `2`), before
`--strict` or an exit-`1` "N error(s)" outcome ever come into play. See
the [CLI reference](../../../../docs/src/reference/cli-reference.md#apimock-validate)
for the detail.

**Note the `./`.** `--config apimock.toml` (no `./`) currently fails
to resolve the path even though the file is right there - a real quirk
in the current release, not a typo in this README. `apimock` with no
flags at all, and `match-test --rule-set` below, are both unaffected.

## `apimock match-test`

Builds a synthetic request from CLI flags and checks it against a rule
set directly - no server, no `curl`. Useful for asking "which rule
would this request hit, and why" while authoring a rule set.

A gold-tier order matches the first, more specific rule:

```sh
$ apimock match-test --rule-set apimock-rule-set.toml \
    --path /orders --method POST --body '{"customer":{"tier":"gold"}}'
Rule #1: /orders  MATCH ★
  ✓  url_path equal "/orders"
  ✓  method POST (actual: POST)
  ✓  body.json "customer.tier"  ==  "gold"  (actual: "gold")

Rule #2: /orders  MATCH
  ✓  url_path equal "/orders"
  ✓  method POST (actual: POST)

Result: MATCH (rule #1)
```

A non-gold order falls through to the second, more general rule - note
rule #1 is shown failing on exactly the condition that excluded it:

```sh
$ apimock match-test --rule-set apimock-rule-set.toml \
    --path /orders --method POST --body '{"customer":{"tier":"silver"}}'
Rule #1: /orders  NO MATCH
  ✓  url_path equal "/orders"
  ✓  method POST (actual: POST)
  ✗  body.json "customer.tier"  ==  "gold"  (actual: "silver")

Rule #2: /orders  MATCH ★
  ✓  url_path equal "/orders"
  ✓  method POST (actual: POST)

Result: MATCH (rule #2)
```

A `GET` matches neither rule (both require `POST`) - exit code `1`,
the "no match" signal a CI step would check for:

```sh
$ apimock match-test --rule-set apimock-rule-set.toml --path /orders --method GET
Rule #1: /orders  NO MATCH
  ✓  url_path equal "/orders"
  ✗  method POST (actual: GET)
  ✗  body (request has no JSON body)

Rule #2: /orders  NO MATCH
  ✓  url_path equal "/orders"
  ✗  method POST (actual: GET)

Result: NO MATCH
$ echo $?
1
```

Exit codes: `0` matched, `1` no rule matched, `2` an argument or input
error (bad flag, file not found, invalid JSON body).