Guide

Fetch handler


Request handler is defined via fetch key since it is similar to fetch API. The input is a Request object and handler should return a Response or a promise if the server handler is async.

Example:

import { serve } from "srvx";

serve({
  xRemoteAddress: true,
  async fetch(request) {
    return new Response(
      `
        <h1>👋 Hello there</h1>
        <p>You are visiting ${request.url} from ${request.xRemoteAddress}</p>
      `,
      { headers: { "Content-Type": "text/html" } },
    );
  },
});

Additional properties

srvx never patches, overrides or extends globals such as Request and Response. Only few lazy getters prefixed with x will optionally be added to the request object instance to allow server adoption of Request.

You can use xRequest type for TypeScript usage.

request.xRemoteAddress?

For Node.js, (Deno and Bun only if xRemoteAddress server option is enabled), request.xRemoteAddress allows to access connected client's ipv4/ipv6 address or hostname.

import { serve } from "srvx";

serve({
  xRemoteAddress: true,
  fetch: (request) =>
    new Response(`Your ip address is ${request.xRemoteAddress}`),
});
In order to to provide cross-runtime consistency, a small wrapper function will be enabled for Deno and Bun runtimes if xRemoteAddress option is set.

request.xNode?

Node.js is supported through a proxy that wraps node:IncomingMessage as Request and converting final state of node:ServerResponse to Response.

If access to the underlying Node.js request and response objects is required (only in Node.js runtime), you can access them via request.xNode?.req (node:IncomingMessage) and request.xNode?.res (node:ServerResponse).

import { serve } from "srvx";

serve({
  fetch: (request) => {
    if (request.xNode) {
      console.log("Node.js req path:", request.xNode?.req.path);
      req.xNode.res.statusCode = 418; // I'm a teapot!
    }
    return new Response("ok");
  },
});
srvx implementation of Request proxy directly uses the underlying node:IncomingMessage as source of trust. Any changes to Request will be reflected to the underlying node:IncomingMessage and vise-versa.
Read more in Node.js support.