Skip to content

Extending the Proxy

The proxy is designed for customization through several trait boundaries. Each controls a different aspect of the proxy's behavior.

TraitControlsDefault Implementation
Router / RouteHandlerPath-based pre-dispatch request interceptionStsRouterExt, OidcRouterExt
MiddlewarePost-auth dispatch interception and post-dispatch observationMeteringMiddleware (multistore-metering)
BucketRegistryBucket lookup, authorization, and listingStaticProvider (static file config)
CredentialRegistryCredential and role storageStaticProvider (static file config)
ProxyBackendHow the runtime interacts with backends, including the forward() method that provides runtime-native HTTP transport for backend forwardingServerBackend, WorkerBackend

When to Customize What

Custom Route Handler — You want to intercept requests before the proxy pipeline (e.g., health checks, metrics endpoints, custom authentication flows). Implement the RouteHandler trait on a struct and register it via router.route(path, handler). Override individual HTTP method handlers (get, post, etc.) for method-specific behavior, or override handle directly for method-agnostic handlers. Handlers receive path parameters via req.params.get("name") when using parameterized routes like /api/items/{id}.

Custom Middleware — You want to intercept requests after identity resolution (e.g., rate limiting, logging, usage metering). Implement the Middleware trait with a handle method for pre-dispatch logic and optionally after_dispatch for post-response observation. Register via gateway.with_middleware(my_middleware). The multistore-metering crate provides MeteringMiddleware<Q, U>, which combines a QuotaChecker (pre-dispatch quota enforcement) with a UsageRecorder (post-dispatch usage tracking). The CF Workers example uses this to enforce per-bucket bandwidth quotas via Durable Objects — see DoBandwidthMeter in examples/cf-workers/src/metering.rs.

Custom Forwarding — You're deploying to a new runtime and need to provide an HTTP client for backend forwarding. Forwarding is not a separate trait: implement the forward() method on the ProxyBackend trait with your runtime's native HTTP client. The response body type is the ResponseBody associated type, allowing zero-copy streaming (e.g., web_sys::Response on CF Workers).

Custom Bucket Registry — Your namespace mapping needs identity-aware authorization, external API calls for bucket lookup, or a different bucket listing strategy.

Custom Credential Registry — You want to store credentials/roles in a backend not already supported (e.g., etcd, Redis, Consul), or you need to derive them from another source.

Custom Backend — You're deploying to a runtime that's neither a standard server nor Cloudflare Workers (e.g., AWS Lambda, Deno Deploy), or you need a different HTTP client.