Compare StripPrefix and RewritePath. When would you choose one over the other?
answer
- StripPrefix = drop N leading segments
- RewritePath = regex + replacement
- $\{segment} backslash escapes Spring placeholder
- RewritePath strictly more expressive
- Both mutate downstream path, not query
basics
~20 sBoth change the path sent downstream. StripPrefix removes a fixed number of leading path segments. RewritePath uses a regex to transform the path into any shape. Use StripPrefix for simple prefix removal, RewritePath when you need pattern-based rewriting.
solid answer
~40 sStripPrefix takes a count N and drops that many leading path segments before forwarding. `StripPrefix=2` turns `/api/users/42` into `/42`. It is simple and positional — good when the gateway just adds a fixed prefix the backend doesn't care about. RewritePath takes a regex and a replacement and rewrites the whole path. `RewritePath=/api/(?<segment>.*), /$\{segment}` turns `/api/users/42` into `/users/42`. RewritePath is more powerful: it can capture groups, reshape arbitrary paths, and keep part of the path. Note the replacement uses `$\{}` in YAML (the backslash escapes Spring's own property placeholder resolution so the regex group reference survives). Choose StripPrefix for pure fixed-segment removal; choose RewritePath when the transformation isn't just chopping N leading segments — e.g. reordering, conditional capture, or partial rewrites.
code
kotlin · 17 lines@Bean
fun routes(builder: RouteLocatorBuilder): RouteLocator =
builder.routes()
.route("strip") { r ->
r.path("/api/users/**")
.filters { f -> f.stripPrefix(2) } // /api/users/42 -> /42
.uri("http://users-service:8080")
}
.route("rewrite") { r ->
r.path("/api/**")
.filters { f ->
// /api/users/42 -> /users/42
f.rewritePath("/api/(?<segment>.*)", "/\${segment}")
}
.uri("http://users-service:8080")
}
.build()go deeper
Knows StripPrefix removes a prefix and RewritePath uses a pattern.
Explains segment-count vs regex, the ${} escape, and when each fits.
Discusses filter ordering interactions and expressiveness trade-offs.
Considers readability/maintainability of regex rewrites vs declarative StripPrefix at scale.
Both **StripPrefix** and **RewritePath** are per-route GatewayFilter factories that mutate the **request path** before the request is proxied downstream. They exist because the gateway's public URL structure often differs from the backend's internal one. **StripPrefix.** Argument is an integer count of path segments to remove from the front. ```yaml filters: - StripPrefix=2 ``` Incoming `/api/users/42` → forwarded `/42`. It counts *segments* (parts between slashes), not characters. It always removes from the left and cannot conditionally keep or reorder anything. Use it when the gateway prefix (e.g. `/api/users`) is routing metadata the downstream service should never see. **RewritePath.** Two arguments: a **regex** to match against the path and a **replacement** template. ```yaml filters: - RewritePath=/api/(?<segment>.*), /$\{segment} ``` Incoming `/api/users/42` → `/users/42`. Named group `segment` captures `users/42`, and the replacement injects it. **The `$\{...}` escaping gotcha.** Spring itself performs `${...}` property placeholder substitution on configuration values. If you wrote `/${segment}` Spring would try to resolve a property named `segment` at startup and fail. Writing `$\{segment}` escapes that so the literal `${segment}` reaches the RewritePath factory, which then interprets it as a regex replacement reference. This trips up almost everyone the first time. **Capabilities compared.** - StripPrefix: only removes N leading segments. Deterministic, trivial. - RewritePath: full regex — can strip, add, reorder, conditionally capture, insert constants, collapse segments. It can even *add* a prefix (e.g. rewrite `/foo` to `/internal/foo`), which StripPrefix cannot. **Order matters.** Filters run in sequence. If you combine `StripPrefix` and `RewritePath` on the same route, the second operates on the already-modified path, so ordering changes the result. **When to choose which.** Prefer **StripPrefix** for the common, readable case of dropping a known fixed prefix — it is self-documenting. Reach for **RewritePath** when the mapping is not a simple left-chop: you need to keep part of the prefix, reorder, add a segment, or apply a pattern. RewritePath is strictly more expressive but harder to read and to get right (regex + escaping), so don't use it where StripPrefix suffices. **Common mistakes.** Off-by-one on StripPrefix count (leading empty segment from the initial slash does not count). Forgetting the regex must match the *entire* path for the replacement to apply as intended. Using `${}` without the backslash escape. Assuming these change the query string — they operate on the path; query parameters pass through unless a query-specific filter is used.
- Why do you write $\{segment} instead of ${segment} in YAML RewritePath?Because Spring resolves ${...} as a property placeholder at config-load time. The backslash escapes it so the literal ${segment} reaches RewritePath, which treats it as the regex capture-group replacement.
- Can StripPrefix add a prefix or reorder segments?No. StripPrefix can only remove a fixed number of leading segments. For adding/reordering you need RewritePath (or PrefixPath to prepend).
saying these in an interview costs you the question
- Claiming StripPrefix uses regex
- Writing ${segment} without escaping and expecting it to work
- Thinking these filters modify query parameters too
- Off-by-one: counting the leading slash as a segment