skip to content

Record and Playback

Pointing a stub server at the real service, driving the client through it, and turning the captured traffic into mappings. What comes back is a first draft, not a finished stub set.

on this pageshow

explore

questions

5

How do you start WireMock standalone so it records the kayak-rental API into stub mappings?

level: juniorimportance: must knowfreq 68%

answer

  1. two launcher flags, not one
  2. forward first, then keep the answer
  3. something real must answer the call
  4. --proxy-all pairs with --record-mappings
  5. --match-headers widens what recorded stubs match

basics

~20 s

Run WireMock standalone with --record-mappings and --proxy-all pointed at the kayak-rental base URL. Every request is forwarded upstream and the real reply is written back as a stub mapping. Large response bodies are extracted into separate body files.

solid answer

~40 s

WireMock standalone turns into a recorder with two launcher flags. `--proxy-all=https://kayaks.riverbend.example` makes WireMock forward everything the client sends — `GET /fleet/boats?site=lower-weir`, `POST /rentals` — to the real kayak-rental service and hand the genuine response back. WireMock's `--record-mappings` is the half that keeps things: each proxied exchange is written out as a WireMock stub mapping, with response bodies large enough to be extracted placed in `__files` and referenced from the mapping. Add WireMock's `--match-headers=Accept,X-Kayak-Site` when the upstream genuinely varies its answer by header, so the recorded mappings match on those headers and not on method and URL alone. `--print-all-network-traffic` prints every exchange to the console while you drive the client, which is how you confirm the traffic really went through WireMock. What lands on disk is a first draft; read it before committing it.

code

bash · 6 lines
bash
java -jar wiremock-standalone.jar \
  --port 8089 \
  --proxy-all=https://kayaks.riverbend.example \
  --record-mappings \
  --match-headers=Accept,X-Kayak-Site \
  --print-all-network-traffic

go deeper

for a junior

Know the pair by name: --proxy-all sends traffic to the real kayak-rental service, --record-mappings keeps the result. Be ready to say why neither one alone produces a usable stub set.

for a middle

Explain what the recorder writes into a mapping and where large bodies go, and why --match-headers changes the generated match criteria rather than the recorded response.

for a senior

Be ready to diagnose an empty capture. Show how you prove the client actually traversed WireMock, and describe what you strip out of a recorded set before it reaches a repository.

for a principal

Own the policy question: who may record against a live upstream, what may be captured, and how a recorded set is reviewed so credentials and volatile values never become committed fixtures.

## What WireMock's recorder actually is WireMock's recorder is not a separate program. It is the same stub server, put into a mode where it forwards what it is asked for to a real service, keeps the real reply, and writes the pair out as a stub mapping. The point is to skip the guessing. Instead of hand-writing a stub for `GET /fleet/boats?site=lower-weir` and inventing what the kayak-rental service returns for it, you put WireMock in front of the real service, drive the client through WireMock, and let the exchanges become mappings. For a standalone WireMock — the shaded jar or the container image — launcher flags arrange that, and they divide cleanly into the ones that make traffic reach a real service and the one that keeps the result. ## The flags that matter - **`--proxy-all=https://kayaks.riverbend.example`** makes WireMock forward every request it receives to that base URL and return the upstream's genuine status, headers and body to the client. On its own it captures nothing; it only guarantees there is a real answer available to capture. - **WireMock's `--record-mappings`** is the half that keeps things. With it on, each proxied exchange is converted into a WireMock stub mapping: the request WireMock saw supplies the match criteria, the upstream's reply supplies the response. - **WireMock's `--match-headers=Accept,X-Kayak-Site`** widens what the generated mappings match on. Without it a recorded mapping keys on method and URL; with it, the named request headers become part of the match as well. Reach for it when the kayak-rental service really does vary its answer by header — a site code, a content type — and not otherwise. - **WireMock's `--enable-browser-proxying`** is the alternative to `--proxy-all` when the client cannot be re-pointed at WireMock's base URL. WireMock then behaves as an HTTP proxy the client is configured to use and takes each destination from the request's own absolute URI, so a single session can capture calls to several hosts. - **WireMock's `--print-all-network-traffic`** prints every request and response as it crosses the server. It records nothing at all, but it is how you prove the client is going through WireMock rather than straight out to the network. ## What lands on disk A recorded mapping is an ordinary WireMock stub mapping — once it exists there is nothing special about it. WireMock writes response bodies large enough to be extracted as separate body files under `__files`, referenced from the mapping instead of being inlined, which keeps a two-hundred-boat availability payload out of the mapping JSON. That gives a WireMock set with a very predictable shape: - one mapping per distinct request WireMock saw, so a client that polls `GET /availability` sixteen times can leave sixteen near-identical mappings behind; - match criteria taken from exactly the URL that was sent, query string and all, so `?site=lower-weir&hours=3` and `?hours=3&site=lower-weir` become two separate mappings; - response bodies that are literally what the kayak-rental service returned that afternoon, including timestamps, generated `rentalId` values and any cookie it issued; - whichever request headers you asked WireMock for with `--match-headers`, and none of the ones you did not. ## Why the output is a first draft The recorder is faithful, not thoughtful. It has no idea which parts of a kayak-rental response are the contract and which are that afternoon's accidents, so it keeps all of them. Three consequences are worth saying out loud: 1. **Secrets travel.** An `Authorization` header, a session cookie or a customer identifier sitting in a recorded body is now in a file you are about to commit, and nothing in WireMock redacts it for you. 2. **Volatile values become fixtures.** A recorded `availableFrom` timestamp is frozen at the instant of capture and will read as stale for as long as the mapping lives. 3. **Over-specific matching becomes flakiness.** Every header you captured is now something the client must reproduce exactly; a correlation identifier that changes per run will simply stop matching. So the honest sequence is record, read, prune, then commit — never record and commit. ## Where capture is switched on, by product | product | how capture is switched on | |---|---| | WireMock, from the launcher | `--record-mappings` alongside `--proxy-all` or `--enable-browser-proxying` | | WireMock, on a running server | `startRecording(...)` and `stopRecording()`, or `POST /__admin/recordings/start` | | Mountebank | `recordRequests` on the imposter, with a `proxy` response leaving recorded stubs behind | ## The mistake that wastes an afternoon The commonest failure here is not a wrong flag; it is a client that never went through WireMock at all. The recorder then produces an empty or near-empty set, and the natural reading — that the flags did not work — is wrong. Check the console first. If `--print-all-network-traffic` prints nothing while you exercise the kayak-rental client, the client is still resolving the real host directly, and no flag on WireMock's side can change that. Fix the client's base URL, or switch to WireMock's `--enable-browser-proxying` and configure the client's proxy settings, and the same two capture flags will start producing mappings immediately.

  • The kayak-rental client hard-codes its base URL. How do you record it without editing the client?
    In WireMock, start with `--enable-browser-proxying` instead of `--proxy-all` and point the client's JVM or OS HTTP proxy settings at WireMock. WireMock then takes each destination from the request's own absolute URI rather than from a single configured target, so the hard-coded host still works and the traffic is still captured. Pair it with `--record-mappings` exactly as before.
  • Why is a WireMock mapping set straight out of --record-mappings usually not committable as-is?
    In WireMock the recorder writes one mapping per distinct exchange, matching the exact URL and method it saw. That set carries whatever the kayak-rental service happened to return — session identifiers, timestamps, any credential echoed back in a header — plus one mapping per query-string permutation. It needs pruning, and where headers were captured it needs tightening, before it belongs in a repository.

saying these in an interview costs you the question

  • Thinks --record-mappings records without any proxy target
  • Believes recorded mappings are safe to commit unreviewed
  • Expects recorded stubs to match on headers by default
  • Assumes the recorder invents responses the upstream never sent
  • Blames the flags when the client bypassed WireMock entirely
open as a page

In WireMock, what do startRecording() and stopRecording() do to kayak-rental traffic?

level: juniorimportance: must knowfreq 61%

basics

~20 s

In WireMock, startRecording puts the running server into recording mode against a target base URL. WireMock's stopRecording ends the session and returns a SnapshotRecordResult holding the stub mappings built from the traffic. Both are also WireMock admin routes.

open as a page

In Mountebank, what do recordRequests, mb save and mb replay do with kayak-rental traffic?

level: middleimportance: should knowfreq 49%

basics

~20 s

In Mountebank, recordRequests makes an imposter keep every request it receives, and a proxy response saves the real replies as new stubs. mb save writes that configuration to a file; mb replay strips the proxies so recorded stubs answer.

open as a page

In WireMock, how does snapshotRecord() differ from a startRecording() session for kayak-rental traffic?

level: middleimportance: should knowfreq 54%

basics

~20 s

In WireMock, startRecording arms a session ahead of time and proxies to the target from that moment. WireMock's snapshotRecord works backwards instead, turning traffic the server has already served into stub mappings, so it needs no session opened first.

open as a page

How would you standardise what a WireMock recording of the kayak-rental API is allowed to capture?

level: principalimportance: should knowfreq 44%

basics

~20 s

Fix the capture shape in one place: a shared WireMock record spec naming which request headers are captured, which bodies are extracted to files, and how repeats are handled. Then require that recorded mappings are read before anything is committed.

open as a page