skip to content

In WireMock, what does urlPathTemplate() match, and what does withPathParam() add?

level: middleimportance: nice to knowfreq 42%

answer

  1. placeholders, not patterns
  2. one segment per brace pair
  3. the path only, query ignored
  4. names give a segment a handle
  5. withPathParam binds to a template name

basics

~20 s

WireMock's urlPathTemplate matches a request path against a template such as /bindery/v2/orders/{orderId}, ignoring the query string. Each placeholder becomes a named variable. WireMock's withPathParam then constrains one of those variables with a value matcher such as equalTo or matching.

solid answer

~50 s

WireMock's `urlPathTemplate("/bindery/v2/orders/{orderId}/quires")` matches the request **path** against a template: the literal segments must line up and each `{name}` placeholder consumes exactly one path segment. Like WireMock's `urlPathEqualTo(`, it is a path matcher, so whatever query string the client sends is ignored. What it adds over a plain regex is that the varying segments become **named**, and WireMock's `withPathParam("orderId", equalTo("BND-4417"))` then applies an ordinary value matcher to one of those names — so a single mapping can accept every order id, or narrow to one, without you rewriting the URL pattern. `withPathParam(` is only meaningful alongside `urlPathTemplate(`, because the other WireMock URL matchers produce no names for it to refer to. Reach for the template when a path carries identifiers you want to talk about by name; WireMock's `urlPathMatching("/bindery/v2/orders/[^/]+/quires")` matches the same requests but leaves the captured segment anonymous.

go deeper

for a junior

Recall that WireMock's urlPathTemplate matches a path written with {name} placeholders and that each placeholder covers exactly one segment. Knowing it looks at the path only, like urlPathEqualTo, is enough at this level.

for a middle

Explain the pairing: the template creates names and withPathParam applies a value matcher to one of them. Be ready to say why withPathParam is meaningless beside urlPathMatching, which captures nothing by name.

for a senior

Argue the template-versus-regex choice on a real stub set — readability and named constraints against a regex's ability to span segments. Mention that renaming a placeholder silently orphans the matchers bound to it, which no compiler will catch.

for a principal

Decide whether a stub set should mirror the provider's documented path templates at all, and what that buys when the upstream paths change. Weigh that maintenance shape against a smaller set of broader regex mappings maintained by fewer people.

## What a path template is WireMock's `urlPathTemplate(` takes a **path template** — a path in which one or more segments are written as `{name}` placeholders — and matches an incoming request's path against it. For the bookbindery order API, the template `/bindery/v2/orders/{orderId}/quires` says: three fixed segments, then exactly one segment of unconstrained content bound to the name `orderId`, then the fixed segment `quires`. The literal parts must line up exactly and each placeholder consumes exactly one segment, so `/bindery/v2/orders/BND-4417/quires` matches while `/bindery/v2/orders/BND-4417/quires/3` does not. Like WireMock's `urlPathEqualTo(` and `urlPathMatching(`, `urlPathTemplate(` is a **path** matcher. The query string is not part of what it compares, so `/bindery/v2/orders/BND-4417/quires?trim=true` matches the same template with nothing extra written. ## What withPathParam adds A placeholder on its own only asserts that some segment is present in that position. WireMock's `withPathParam(` then applies an ordinary value matcher to one named placeholder: - `withPathParam("orderId", equalTo("BND-4417"))` in WireMock narrows the stub to a single bookbindery order. - `withPathParam("orderId", matching("BND-[0-9]{4}"))` in WireMock narrows it to ids of the house shape and nothing else. - `withPathParam("orderId", containing("4417"))` in WireMock narrows it loosely, which is usually a smell rather than a design. - Omitting `withPathParam(` altogether leaves the placeholder wide: every order id matches, but the *shape* of the path is still asserted. Two consequences fall out of that design, and both get asked about: 1. **`withPathParam(` is meaningless without `urlPathTemplate(`.** WireMock's other URL matchers capture nothing by name, so the first argument would have no referent. If you find `withPathParam(` sitting on a stub whose URL matcher is `urlPathMatching(`, the constraint is not doing what its author believed. 2. **The placeholder name is a contract.** Renaming `{orderId}` to `{id}` in a WireMock template silently orphans every `withPathParam("orderId", …)` attached to that stub — the template still matches, and the narrowing you thought you had is gone. ## Template versus regex The template and the path regex overlap heavily, and choosing between them is the substance of the question. | Written as | Compares | Varying part is | |---|---|---| | WireMock `urlPathTemplate("/bindery/v2/orders/{orderId}")` | the path only | named `orderId` | | WireMock `urlPathMatching("/bindery/v2/orders/[^/]+")` | the path only | anonymous | | WireMock `urlPathEqualTo("/bindery/v2/orders/BND-4417")` | the path only | fixed | Reasons to prefer WireMock's template: - It reads like the provider's own documented path, so a reviewer can diff the stub against the API description by eye. - The constraint on the variable is expressed in the same value-matcher vocabulary used everywhere else in a WireMock stub, rather than smuggled into regex syntax. - You can tighten or loosen the variable without touching the path, which keeps the two decisions independent in review. Reasons to prefer WireMock's regex: - A pattern that must span a slash, or make a whole trailing segment optional, is expressible as a regex and not as a set of single-segment placeholders. - One regex can cover a family of related paths where a template would need one stub per shape. ## Where it goes wrong in practice - Expecting `{orderId}` to swallow several segments. It consumes one, so `/bindery/v2/orders/2026/BND-4417` needs a two-placeholder template. - Expecting the template to constrain the query string. It does not; a WireMock path matcher never sees it. - Forgetting that the method still comes from the surrounding builder, so `get(urlPathTemplate("/bindery/v2/orders/{orderId}"))` is what pins GET. - Assuming an unconstrained placeholder matches *nothing* until `withPathParam(` is added. The opposite is true: it matches everything in that position. ## What one template replaces A concrete count makes the trade visible. Suppose the bookbindery suite needs the order-detail endpoint stubbed for eight fixtures carrying eight different order ids. - With WireMock's `urlPathEqualTo(`, that is eight mappings, each spelling out one id in full, and a ninth the day somebody adds a fixture. - With WireMock's `urlPathTemplate("/bindery/v2/orders/{orderId}")` and no path-parameter matcher, it is one mapping that answers all eight and every id after them. - With the same WireMock template plus `withPathParam("orderId", matching("BND-[0-9]{4}"))`, it is still one mapping, but a malformed id now falls through instead of being cheerfully answered. That third line is the real payoff. The template is not only a shortening device; it is the place where you state what an order id is *allowed to look like*, and it does so without turning the whole path into a regex that a reviewer has to parse character by character. ## The idea elsewhere MockServer has its own named-path-variable matcher, `withPathParameter(`, used with a `request().withPath(` value that carries `{}` placeholders — the same idea reached by a different route. The short version worth remembering is that WireMock's `urlPathTemplate(` buys you *names*, and names are what `withPathParam(` needs to exist. Everything else it does — path only, one segment per placeholder, literals matched exactly — it shares with the plainer path matchers you already know.

  • In WireMock, what happens to a urlPathTemplate stub if you omit withPathParam entirely?
    The placeholder still has to be filled by exactly one path segment, but its content is unconstrained, so every order id matches. WireMock's `withPathParam(` is a narrowing step rather than a declaration: the template alone already asserts the shape of the path, and the parameter matcher only tightens what one named segment may contain.
  • When is WireMock's urlPathMatching a better choice than urlPathTemplate for a varying path?
    When the variation crosses a segment boundary or is optional. A pattern such as `/bindery/v2/orders/[^/]+(/quires)?` cannot be written as a fixed set of single-segment `{name}` placeholders. Templates win when the path shape is fixed and the varying segment deserves a name; regexes win when the shape itself varies from request to request.

saying these in an interview costs you the question

  • Expecting a WireMock placeholder to span several path segments
  • Thinking urlPathTemplate also matches the query string
  • Pairing withPathParam with urlPathMatching, which names nothing
  • Assuming an unconstrained placeholder matches no requests
  • Renaming a placeholder and leaving withPathParam on the old name