Middleware

Middleware is the main composition mechanism in fest.

Shape

Middleware receives (request, next) and can:

  • return a Response immediately
  • call next(request) and return the downstream response
  • replace or mutate the request before passing it on
import type { ServerMiddleware } from "@hornjs/fest";

const poweredBy: ServerMiddleware = async (request, next) => {
  const response = await next(request);
  response.headers.set("x-powered-by", "fest");
  return response;
};

Registering Middleware

import { serve } from "@hornjs/fest";
import { NodeRuntimeAdapter } from "@hornjs/fest/node";

serve({
  adapter: new NodeRuntimeAdapter(),
  middleware: [poweredBy],
  routes: {
    "/": () => new Response("ok"),
  },
  fetch: () => new Response("Not Found", { status: 404 }),
});

Short-Circuiting

Middleware can stop the chain by returning a response directly.

const auth: ServerMiddleware = async (request, next) => {
  if (!request.headers.get("authorization")) {
    return new Response("Unauthorized", { status: 401 });
  }
  return next(request);
};

Static Files

serveStatic() is implemented as middleware.

import { serve } from "@hornjs/fest";
import { serveStatic } from "@hornjs/fest/static";
import { NodeRuntimeAdapter } from "@hornjs/fest/node";

serve({
  adapter: new NodeRuntimeAdapter(),
  middleware: [serveStatic({ dir: "./public" })],
  fetch: () => new Response("Not Found", { status: 404 }),
});

Request Logging

The optional logger lives in a separate subpath export.

import { serve } from "@hornjs/fest";
import { log } from "@hornjs/fest/log";
import { NodeRuntimeAdapter } from "@hornjs/fest/node";

serve({
  adapter: new NodeRuntimeAdapter(),
  middleware: [log()],
  routes: {
    "/": () => new Response("ok"),
  },
  fetch: () => new Response("Not Found", { status: 404 }),
});

Plugins

ServerPlugin runs during Server construction and can modify server.options or register process-level behavior.

fest itself uses plugins internally for:

  • request error normalization
  • graceful shutdown handling in supported runtimes