In Mountebank, what do proxyOnce, proxyAlways and proxyTransparent each do to a proxied request?
answer
- three modes on one proxy response
- they differ in what gets kept
- once: upstream sees each call once
- always forwards every matching request
- transparent never saves the reply
basics
~20 sMountebank's proxyOnce forwards the first matching glossary request to the real service and answers later identical ones from the saved reply. proxyAlways forwards every matching request upstream. proxyTransparent forwards everything and saves nothing, staying a pure pass-through.
solid answer
~50 sAll three are values of `mode` on a Mountebank `proxy` response, and they differ only in what the imposter does with the reply that comes back from the translation-glossary service. `proxyOnce` forwards a request that reaches the proxy stub, saves the upstream reply as a new stub keyed by the generated predicate, and answers every later request matching that predicate locally, so the real service sees each distinct call once. `proxyAlways` forwards every matching request upstream and accumulates the replies, which is what you want when the same call must return changing data. `proxyTransparent` forwards and returns without saving anything, so the imposter never stops being a pass-through. The mode is the whole of the choice: `to` decides where traffic goes, `mode` decides whether it keeps going there. In WireMock the equivalent broad mapping returns `aResponse().proxiedFrom("https://glossary.example.com")` and has no mode switch at all.
code
json · 19 lines{
"port": 4547,
"protocol": "http",
"stubs": [
{
"predicates": [
{ "equals": { "method": "GET", "path": "/v2/glossaries/marine-biology/terms" } }
],
"responses": [
{ "is": { "statusCode": 200, "body": { "entries": [], "revision": 41 } } }
]
},
{
"responses": [
{ "proxy": { "to": "https://glossary.example.com", "mode": "proxyTransparent" } }
]
}
]
}go deeper
Be ready to name Mountebank's three proxy modes - proxyOnce, proxyAlways and proxyTransparent - and say in one sentence what each does with the reply that comes back from the real service.
Explain that mode changes only what the imposter keeps, never which requests are forwarded, and show why proxyOnce quietly stops contacting the real service after the first call of each shape.
Show that you pick the mode from the endpoint's behaviour: proxyTransparent when unfaked traffic must always be real, proxyAlways when the upstream answer legitimately moves between calls.
Own the consequence across suites. A proxyTransparent imposter makes every run depend on a live third party, while proxyOnce trades that dependence for answers that silently age. Say which you would standardise on and what makes you revisit it.
## What a Mountebank `proxy` response actually is A Mountebank **imposter** is one process listening on one port, and its `stubs` array holds the rules it answers with. Each stub has `predicates` that decide whether it applies and `responses` that decide what comes back. A Mountebank response is one of four kinds: `is` (a canned reply you wrote), `inject` (JavaScript that builds a reply), `fault` (a broken connection instead of a reply), or `proxy` — and `proxy` is the one that does not answer at all. It forwards the request to the address in its `to` field, waits for the real translation-glossary service to answer, and hands that answer back to the caller unchanged. That forwarding is the second half of selective pass-through. The imposter holds specific stubs for the glossary paths you are faking — say one that answers `GET /v2/glossaries/marine-biology/terms` with a fixed list of entries — and one broad Mountebank `proxy` stub that carries everything the specific stubs did not answer out to the real service. `mode` is the field that decides what the imposter does with each reply that comes back through that proxy stub. ## The three Mountebank modes, side by side | Mountebank `mode` | forwards | keeps the reply | what upstream sees | |---|---|---|---| | `proxyOnce` | until a saved reply exists | yes | each distinct request once | | `proxyAlways` | every matching request | yes, appended | every request | | `proxyTransparent` | every matching request | no | every request | - Mountebank's **`proxyOnce`** forwards the request, saves the upstream reply as a new stub, and answers every later request that the saved stub's predicate accepts from that saved copy. The real glossary service is contacted once per distinct request shape and then goes quiet for the rest of the run. - Mountebank's **`proxyAlways`** forwards every matching request upstream and appends each reply to the saved stub, so the proxy keeps firing instead of being short-circuited. This is the mode for an endpoint whose answer legitimately changes — a `revision` counter, a remaining-quota field — because the imposter never starts answering from a stale copy. - Mountebank's **`proxyTransparent`** forwards and returns and saves nothing at all. The imposter is a pure conduit for that traffic for as long as it runs, which is what selective pass-through usually wants: the glossary paths you faked stay faked, and everything else genuinely reaches the real service every single time. ## What the mode does not control This is where the field is most often misread. All three Mountebank modes forward. The mode is a decision about the *reply*, not about the *request*: - It does not decide **which** requests reach the proxy stub — that stub's own `predicates`, or their absence, decide that. - It does not decide **where** they go; Mountebank's `to` does. - It does not change the request on the way out; Mountebank's `injectHeaders` does that. - It does not decide what a saved stub keys on; Mountebank's `predicateGenerators` does, and with no generators the saved stub carries no predicates at all. - It does not touch the reply's status code, headers or body. The client sees exactly what the glossary service sent. ## Choosing one for a real suite 1. If the point of the proxy is that unfaked traffic must always be real — the usual reason a broad proxy sits under specific stubs — choose Mountebank's `proxyTransparent`. Nothing accumulates, nothing goes stale, and the arrangement means the same thing on the tenth request as on the first. 2. If you want the first call to be real and the rest to be fast and offline, choose Mountebank's `proxyOnce`, and then take `predicateGenerators` seriously, because that generated predicate is what decides whether the second call counts as the same request. 3. If the endpoint's answer moves between calls and you still want every exchange to reach the real service, choose Mountebank's `proxyAlways`. ## The failure each mode produces Every mode buys something and charges for it, and naming the charge is what an interviewer is listening for. - `proxyOnce` fails by going quiet: a suite that was exercising the real translation-glossary service stops doing so after the first call of each shape, and a change upstream no longer shows up anywhere. - `proxyAlways` fails by volume: replies accumulate on the saved stub for the life of the imposter, and a long run leaves a pile nobody reads. - `proxyTransparent` fails by dependence: every run needs the real glossary service reachable and credentialled, so an outage there is an outage in your pipeline. None of those is a bug. Each is the price of the mode you chose, and the choice is a single string in the imposter definition.
- Which Mountebank proxy mode fits a glossary endpoint whose revision counter changes on every call?`proxyTransparent` if you only want the live answer, `proxyAlways` if you also want each exchange kept. Both forward every matching request, so the client always sees the current revision. `proxyOnce` is wrong here: it saves the first reply and answers from it afterwards, which pins the counter at whatever value the first call happened to return.
- What does the `to` field on a Mountebank proxy response accept, and how is the path decided?`to` takes the base address of the real service, such as `https://glossary.example.com`. Mountebank forwards the incoming request to that address, so the path and query the client sent are what the upstream receives. If the imposter must reach a different path than the client asked for, that is a different `to` or a different stub, not a `mode` setting.
saying these in an interview costs you the question
- Thinking proxyOnce forwards only one request in total
- Calling proxyTransparent a recording mode
- Believing the mode decides which requests reach the proxy stub
- Assuming proxyAlways overwrites the previous saved reply
- Expecting the mode to change the reply the client sees