Skip to content

Proxy & ctx.forward() reference

Proxy passthrough

Unmatched routes forward to proxy.target:

ts
await mockr({
  port: 4000,
  proxy: { target: 'https://api.example.com' },
  endpoints: [
    { url: '/api/orders', data: [/* ... */] }, // mocked
    // everything else → api.example.com
  ],
});
OptionDescription
proxy.targetUpstream base URL. Required for ctx.forward().
proxy.changeOriginRewrite Host header to match target (default true).
proxy.headersStatic headers to inject on every forwarded request.
proxy.timeoutMsRequest timeout (default 30000).

Proxying drops hop-by-hop headers (connection, keep-alive, transfer-encoding, etc.) per RFC 7230.

server.enableProxy() / setProxyTarget()

Toggle and retarget at runtime — useful when switching between dev and staging during a session.

ctx.forward() — forward then mutate

Inside a handler, ctx.forward() hits upstream and resolves with the response. You can return it as-is or mutate first.

ts
{
  url: '/api/orders',
  handler: handler({
    fn: async (req, ctx) => {
      const upstream = await ctx.forward();
      // upstream: { status, headers, body }

      // tag every order with `_mocked: true` for client-side detection
      if (Array.isArray(upstream.body)) {
        upstream.body = upstream.body.map((o) => ({ ...o, _mocked: true }));
      }
      return upstream;
    },
  }),
}

Override request

ctx.forward({ url, method, headers, body }) lets you forward to a different upstream URL or rewrite the request before sending.

ts
const upstream = await ctx.forward({
  url: '/v2/orders',                  // hit a different path on `proxy.target`
  headers: { 'X-Forwarded-By': 'mockr' },
});

When to use which

GoalTool
All unmatched routes → upstreamproxy: { target }
Mock some routes, proxy the restproxy: { target } + matching endpoints
Mock + augment one routehandler + ctx.forward()
Record traffic to map → mocksrecorder + Chrome extension

MIT License