Skip to main content

API gateway wildcard routing: expose variable path depth without losing control

How to set up API gateway wildcard routing in Zerq: scope a wildcard proxy, restrict methods, test allow and deny paths, and watch suffixes in request logs.

  • api-gateway
  • routing
  • wildcard-proxy
  • platform-engineering
  • how-to
Zerq team

Some backend paths cannot be enumerated. A document store that serves /storage/reports/2026/q1.csv today will serve /storage/region/eu-west/customers/8841/export.json tomorrow. The path depth is variable, the suffixes are generated by the backend, and no one can list every valid route ahead of time. Platform teams facing this either define hundreds of near-identical endpoints, or they punch a blanket pass-through hole in the gateway and hope nothing unexpected travels through it.

API gateway wildcard routing is the correct tool for this situation, and it is also the easiest place in a gateway configuration to quietly lose control. One route now matches an unbounded family of paths, so every guardrail that normally sits on an individual endpoint has to be applied deliberately: method restrictions, client and profile checks, rate limits, and log visibility into what suffixes actually arrive. In Zerq, a wildcard proxy is a first-class route type that inherits all of those controls, and this guide walks through the full rollout: authoring the route, layering the guardrails, testing allow and deny cases before publishing, and monitoring the suffix traffic once it is live.

This is a working guide. Every field name, header, and screen below comes from the product, and by the end you will have a wildcard route that behaves like a scoped endpoint family rather than an open tunnel.

Why the usual approaches break down

The first instinct is to avoid wildcards entirely and enumerate routes. That works until the path space grows. A file delivery API with per-customer, per-period, per-format paths produces a combinatorial route table that nobody maintains. Documentation drifts, new suffix families silently 404, and every backend change becomes a gateway change. Enumerating routes converts a routing problem into a synchronization problem, which is worse.

The second instinct is the catch-all proxy. Kong's route paths, AWS API Gateway's {proxy+} greedy variable, and Azure API Management's wildcard operations all let you forward everything under a prefix. The routing works, but the controls around it thin out. A greedy variable in AWS API Gateway matches every method and every depth unless you build separate method-level operations around it. In Kong, the catch-all route sits outside your documented API surface, so the developer portal and the OpenAPI spec no longer describe what the gateway actually serves. In practice, the catch-all becomes the least-governed route in the estate precisely because it carries the least-predictable traffic.

The underlying problem is that most gateways treat a wildcard as an escape hatch from the endpoint model instead of a member of it. Once a route is an escape hatch, it escapes everything: schema validation, portal testing, per-endpoint audit context. What you want is a route that matches variable depth but still participates in access control, testing, and observability like any other endpoint.

How Zerq models API gateway wildcard routing

In Zerq, routing happens in two stages. A request first matches a collection by its base path, then matches a proxy inside that collection by path and method. A wildcard proxy is an ordinary proxy whose path ends in /*, and the suffix it captures is rewritten onto the target path when the request is forwarded upstream.

The route configuration for a partner file delivery endpoint looks like this:

Collection base path:  /partner/v1        # matched first; scopes the route family
Proxy path:            /files/*           # suffix wildcard; matches any depth below /files/
Target path:           /storage/*         # the captured suffix is appended here
Methods:               GET                # only what the upstream should ever receive

A request to https://gateway.example.com/partner/v1/files/customers/acme/invoices/2026-03 matches the /partner/v1 collection, passes the method check, matches the /files/* proxy, and is forwarded upstream as /storage/customers/acme/invoices/2026-03. The suffix travels through unchanged; the prefix is rewritten.

Matching precedence is the part worth internalizing, because it is what lets wildcards coexist with explicit routes. The gateway evaluates in this order:

  1. Match the collection base path. No match returns 404 before any proxy is considered.
  2. Check the method against the proxy's allowed methods. A blocked method returns 405.
  3. Try explicit proxy paths first, including parameterized paths like /files/{fileId}/metadata.
  4. Only if no explicit route matches, try wildcard proxies, rewrite the suffix onto the target path, and forward upstream.

Explicit routes always win over the wildcard. This means you can carve critical operations out of the wildcard family and give them their own schemas, parameters, and workflow logic, while the wildcard handles the long tail. The architecture keeps all of this in the single Go binary's routing layer, so there is no separate rule engine to keep in sync.

When a wildcard is the wrong choice

Before creating one, apply this test. Choose a parameterized path instead of a wildcard when any of these hold:

  1. The path depth is fixed. /users/{userId}/orders/{orderId} is two segments, always. Define it explicitly and get type validation on each parameter for free.
  2. You need request schema validation on the route. Schemas attach to explicit proxies, and validation is most useful where the input shape is known.
  3. The route carries a write operation that matters. Payments, consent changes, and record mutations deserve their own proxy with their own parameters, workflow, and audit context.
  4. Consumers need precise portal documentation for the route. Explicit proxies generate exact OpenAPI entries; a wildcard documents a family, not an operation.

Reserve wildcards for what they are good at: file and blob download paths, static asset passthrough, and nested partner routes where the backend generates the suffix and the depth genuinely varies.

Step by step: roll out a wildcard proxy safely

The rollout below follows the pattern we recommend to every team: author in draft, layer guardrails, prove allow and deny behavior with real requests, and only then publish.

1. Create the proxy in draft

  1. Open the collection in the Management UI and click Add Proxy. The six-step wizard opens.
  2. In the Info step, set the Name (for example Partner file download) and a Description. Both appear in the Developer Portal, so write the description for the consumer, including examples of valid suffixes.
  3. In the Route step, select only the methods the upstream supports, usually just GET for file delivery. Set Incoming Path to /files/* and Target Path to /storage/*.
  4. Skip Parameters and Schema for the wildcard route itself; they belong on any explicit routes you carve out of the family.
  5. In the Review step, click Save as Draft. A draft proxy is not routable through the gateway even if its parent collection is published, so nothing is live yet.

Keep the wildcard under the most specific prefix you can. /partner/v1/files/* is a controlled family; /* at the collection root is a tunnel. Alongside the route itself, write down the acceptable suffix patterns, with examples and non-examples, in the proxy description. Six months from now, that is what tells a reviewer whether an odd-looking suffix in the logs is expected traffic.

2. Layer the access guardrails

The wildcard matches many paths, so the controls that scope who can use it matter more than usual. All of them live in the profile and policy layer described on the security page:

  1. Assign the collection only to the clients that need it. Partners see and reach only their assigned collections, in both the gateway and the portal.
  2. On the consuming profile, set method restrictions to GET. Method checks apply at both the proxy and profile layers, so a DELETE against the file family is refused even if someone later widens the proxy's methods by mistake.
  3. Add the partner's egress IPs or CIDR ranges to the profile IP allowlist, for example 198.51.100.0/24. An empty allowlist admits any source IP; a populated one refuses everything else.
  4. Attach a rate limit policy sized for the file traffic you expect. A wildcard route is where retry storms and crawler-style enumeration show up first, and the policy converts that into 429 responses instead of upstream load.

3. Prove allow and deny behavior with real requests

Test against the draft using the admin tooling, or publish to a staging environment first. Every request through the gateway carries the client and profile headers, so the test calls look exactly like partner traffic:

# Expected allow: a valid deep suffix
curl -i "https://gateway.example.com/partner/v1/files/customers/acme/invoices/2026-03" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Client-ID: partner-acme" \
  -H "X-Profile-ID: prod-partner-acme"

# Expected deny: method not allowed on this route family
curl -i -X DELETE "https://gateway.example.com/partner/v1/files/customers/acme/invoices/2026-03" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Client-ID: partner-acme" \
  -H "X-Profile-ID: prod-partner-acme"

Run a suffix matrix, not a single happy path. Test a shallow suffix (/logo.svg), a medium one (/reports/q1.csv), and a deep one (/region/us-east/customers/42/export.json), and confirm the target path rewrite is correct at each depth. Then confirm the denials: the DELETE returns 405, a request without a valid profile returns 401 or 403, a path outside the wildcard scope returns 404, and a burst past the policy returns 429. Each status code tells you which layer refused the request, which is exactly the property you want when debugging this route later.

Consumers can run the same checks themselves. The Developer Portal testing console detects a wildcard endpoint and renders a dedicated path input where the partner supplies only the suffix, plus custom query parameters if the upstream expects them. The console refuses to send until the suffix is filled in, then shows status, body, and latency for the round trip.

4. Publish, then watch the suffixes

Publish the proxy from the Review step or the status toggle on the proxy list. From this moment the route family is live for assigned clients.

Now the discipline shifts to observability. Zerq logs every request with its full context, and for a wildcard route the fields that matter are:

path:             /partner/v1/files/customers/acme/invoices/2026-03
                  # the actual incoming path, full suffix included
target_endpoint:  https://storage.internal/storage/customers/acme/invoices/2026-03
                  # what the rewrite produced; verifies the mapping in production
method:           GET
status_code:      200
latency_ms:       184
client_id:        partner-acme        # who called
profile_id:       prod-partner-acme   # under which auth configuration
collection:       Partner API v1
client_ip:        198.51.100.14       # checked against the profile allowlist
request_id:       9f2c…               # returned to the caller in X-Request-ID

In the Logs view, filter by path with the wildcard filter /partner/v1/files/* to see the whole family, then narrow by client, status class, or latency. Two reviews are worth scheduling in the first week. First, scan the distinct suffixes that arrived and compare them against your documented patterns; unexpected families mean either a partner integration you did not know about or probing. Second, filter status 4xx on the family: repeated 404s reveal a wrong rewrite or a partner guessing paths, and repeated 405s reveal a client trying methods you deliberately blocked. Because filters are written into the URL, the reviewed view can be bookmarked and shared with the security team as-is. For compliance teams, every one of these entries carries client identity, profile, source IP, and the exact suffix, so the question "who downloaded what, from where, and when" has a direct answer.

If the route misbehaves, rollback is contained: unpublish the proxy to take the family offline without deleting it, or replace the wildcard with narrower static paths for the critical operations and republish after re-testing.

What this looks like in practice

A payments company delivers settlement files to around forty B2B partners. Before the gateway, this ran over per-partner SFTP drops: separate credentials, separate firewall rules, and no unified record of who fetched which file. The integration team spent real time on key rotation and on answering auditor questions from four different log sources.

They moved delivery behind Zerq with a single wildcard route: collection /partner/v1, proxy /files/*, target /storage/*, method GET only. Each partner has a client with their own profile, method-restricted to GET, IP-allowlisted to their egress ranges, and rate-limited to their tier. The one operation that mutates state, acknowledging receipt of a file, is an explicit POST /files/{fileId}/ack proxy with a request schema, carved out of the family and matched ahead of the wildcard by precedence.

The before-and-after for their compliance team is the point. Previously, "show me every settlement file partner X retrieved in March" was a grep across SFTP server logs. Now it is a request log filter: client ID plus path /partner/v1/files/* plus a date range, with source IPs and latencies attached, exportable for the audit. Partners onboard through the portal, test their first download in the console with the suffix input, and copy a working curl command. No SFTP server, no per-partner firewall tickets, one log.

What you get

A wildcard route in Zerq is a governed endpoint family, not a hole in the routing table. Explicit routes take precedence, so critical operations keep their own schemas and workflows. Method restrictions, IP allowlists, and rate limit policies apply to the family exactly as they do to a single endpoint. The portal documents and tests the route with a dedicated suffix input. And every request that matches the wildcard lands in the same request log as the rest of your traffic, with the full suffix, client identity, and rewrite target recorded. If your current gateway treats catch-all routes as an escape from governance, that is the difference to evaluate, and the comparison pages cover how the alternatives handle it.


Zerq is an enterprise API gateway built for regulated industries — one platform for API management, AI agent access, compliance audit, and developer portal, running entirely in your own infrastructure. See how it works or request a demo to walk through your specific requirements.