skip to content

How would you govern a sprawling WireMock mappings/ directory for a museum ticketing API across many teams?

level: principalimportance: should knowfreq 48%

answer

  1. ownership problem with a mechanical signal
  2. count the dead weight every build
  3. never-served set against total loaded
  4. team name in the mapping metadata
  5. GET then DELETE /__admin/mappings/unmatched

basics

~20 s

Measure the catalogue before you police it: WireMock's GET /__admin/mappings/unmatched names every stub a run never served. Record an owner in each WireMock mapping's metadata, and prune only on that evidence, never on a hunch about which stubs look stale.

solid answer

~50 s

Sprawl is an ownership problem with a mechanical signal, so start with the signal. In WireMock, `GET /__admin/mappings/unmatched` returns the stub mappings the running instance never served, and `DELETE` on that same path removes exactly them; take the census at the end of a full suite and publish its size next to the total from `GET /__admin/mappings`. Require a WireMock `metadata` block naming a team on every mapping, so `POST /__admin/mappings/find-by-metadata` answers *who owns these forty stubs* as a query instead of an archaeology exercise. On disk the same WireMock catalogue is `mappings/` plus the bodies under `__files/`, and orphaned body files need their own scan because the server never complains about them. A census taken from a sharded or tag-filtered run describes that run, not the catalogue. Then make the ratio a published number rather than a rule nobody can apply.

code

bash · 15 lines
bash
BASE="http://localhost:8080/__admin"
mkdir -p build

# After the FULL museum ticketing suite: stubs this instance never served.
curl -sS "$BASE/mappings/unmatched" -o build/never-served.json

# The catalogue it is measured against.
curl -sS "$BASE/mappings" -o build/all-mappings.json

# The same catalogue as it sits in the repository.
find mappings -name '*.json' | wc -l
find __files -type f | wc -l

# Only once the census has been reviewed and claimed by its owners:
curl -sS -X DELETE "$BASE/mappings/unmatched"

go deeper

for a junior

Know that a WireMock stub set is mappings/ definitions plus __files/ bodies, and that adding a stub is easy while removing one is not. Be ready to say why a growing catalogue is a maintenance cost.

for a middle

Be ready to explain what GET /__admin/mappings/unmatched measures and what it does not, and to compare its size against the total from GET /__admin/mappings as the ratio that actually describes the catalogue.

for a senior

Show that you gate the prune on the run behind the census: full suite, no shard, no tag filter, owners given a claim window, and deletions landing through review so a reviewer can re-derive the evidence.

for a principal

Own the tradeoff between a catalogue that is trusted and one that is small. Argue for owner metadata as an admission requirement, a published never-served ratio, and a policy that survives the first prune that breaks something.

## What sprawl is, and why a rule alone will not fix it A WireMock instance serves from a set of **stub mappings**, each one a request matcher paired with a canned response. Nothing in the server caps how many there are, nothing expires one, and nothing objects when two of them could answer the same request. A museum ticketing stub set that began as six mappings — session listing, availability, ticket issue, ticket lookup, membership check, refund — is four hundred a year later, because every team added the one case its own suite needed and no team deleted anything. The catalogue is now bigger than anyone's memory of it. That is the real failure: not that the stubs are wrong, but that nobody can say which are still load-bearing, so nobody dares remove one. This is why *delete the stubs you no longer need* fails as a policy — it asks each team to identify a set none of them can see. Governance that starts with a **measurement** works instead, and WireMock ships the measurement in its admin API. ## The census WireMock already gives you | what you want to know | WireMock route | what comes back | |---|---|---| | the whole catalogue | `GET /__admin/mappings` | every stub mapping currently loaded | | the dead weight | `GET /__admin/mappings/unmatched` | the stubs this instance never served | | the prune | `DELETE /__admin/mappings/unmatched` | those stubs dropped from the running instance | | an ownership query | `POST /__admin/mappings/find-by-metadata` | the mappings whose metadata matches | | a bulk retirement | `POST /__admin/mappings/remove-by-metadata` | those mappings dropped | The governing number is the size of the never-served list against the size of the whole catalogue. Turn it into a published metric rather than an opinion: - Take the census at the **end of a full suite run**, because the endpoint reports over the instance's whole lifetime so far. - Record the never-served count and the total count per build, so the trend is visible even when no single build looks alarming. - Treat a rising never-served fraction the way you treat rising build time — a maintenance signal that earns time on the board. - Never act on a census taken from a sharded, tag-filtered or aborted run; that census describes the run, not the catalogue. ## Ownership has to be written into the mapping The census tells you which stubs are unused. It cannot tell you who to ask about them, and that is the question that actually blocks deletion. In WireMock a mapping can carry a `metadata` block, and two admin routes read it, so ownership becomes a query rather than a git-blame expedition. - Require a WireMock `metadata` block on every new mapping, naming a team and the case the stub exists for. - Make WireMock's `POST /__admin/mappings/find-by-metadata` the first step of any prune: pull the never-served set, group it by owner, send each group to its team. - Use WireMock's `POST /__admin/mappings/remove-by-metadata` to retire a whole area at once, rather than deleting mappings one identifier at a time. - Reject a WireMock mapping without owner metadata in code review; that is far cheaper than reconstructing intent a year later. ## The half the admin API cannot see On disk the same catalogue is two directories that WireMock names: `mappings/` for the JSON stub definitions and `__files/` for the response bodies those definitions name with `bodyFileName`. The admin census covers loaded stubs, not files, so the disk half needs its own scan. - A body under WireMock's `__files/` that no mapping references any more is invisible: nothing loads it, nothing warns, and it survives every prune you run through the admin API. - Two mappings can point at the same body file, so a naive *delete the body when you delete the stub* sweep breaks the other one. - A definition committed to WireMock's `mappings/` but never loaded by the instance you censused will not appear in the never-served list either — it was never a stub in that instance at all. - Mountebank concentrates the equivalent persisted state in the directory named by `--datadir`, which makes the same catalogue easy to find and just as easy to let grow. ## A prune sequence a team can actually run 1. Run the **full** suite against one instance, with no tag filter and no sharding, and confirm it finished. 2. Fetch WireMock's `GET /__admin/mappings` and `GET /__admin/mappings/unmatched`, and record both sizes as build artefacts. 3. Group the never-served set by its WireMock owner metadata and circulate it, giving owners a fixed window to claim a stub. 4. Delete the unclaimed definitions in the repository, so the change arrives through review like any other. 5. Re-run the full suite to prove nothing depended on them, then sweep WireMock's `__files/` for bodies no remaining definition names. The point of the sequence is that every deletion is backed by evidence a reviewer can re-derive. A catalogue that shrinks on that basis stays trustworthy. One that shrinks on somebody's judgement of which files look old will eventually take a load-bearing stub with it, and the team will stop pruning for a year afterwards.

  • How would you stop a WireMock mapping set growing faster than anyone can review it?
    Attach the cost to the addition rather than the cleanup. Require owner `metadata` on every new mapping at review time, and reject a new stub that duplicates a path an existing one already matches. Then publish the never-served fraction from `GET /__admin/mappings/unmatched` per build, so growth without use is visible to the team that caused it rather than discovered a year later.
  • Which WireMock mapping would you refuse to delete even though it was never served?
    One whose absence from the census is explained by the run rather than by disuse: an error-path stub only a nightly job exercises, anything belonging to a shard that did not run, and any stub an owner has claimed within the window. Also a stub that went unserved because a broader mapping answered instead — that is an overlap to resolve, not dead weight.

saying these in an interview costs you the question

  • Deleting stubs because the definition file looks old
  • Assuming a large mapping set is automatically a problem
  • Acting on a census taken after a sharded or filtered run
  • Believing the admin API notices orphaned __files/ bodies
  • Treating catalogue size as a rule instead of a measured trend
  • Expecting the never-served list to prove a stub is still correct