A request passes through a chain of functions before it reaches your handler. Each one can answer the request itself or step aside.

firewall -> bans -> your handler

The firewall link is only present when the firewall option is enabled. The bans check always runs, and your handler is simply the last link in the chain.

Writing one

A middleware takes the same context as a handler. Return a response to stop there; return nothing to continue.

1import { Middleware, res_401 } from "apiker";
2
3export const requireToken: Middleware = ({ headers }) => {
4 if (!headers.get("Authorization")) return res_401("No token provided");
5 // returning nothing passes the request on
6};

Running a chain yourself

forwardToMiddleware runs a list in order and returns the first response produced, which lets you apply guards to a single route without touching the global chain.

1import { forwardToMiddleware } from "apiker";
2
3const routes = {
4 "/admin/report": params =>
5 forwardToMiddleware(params, [requireToken, requireAdmin, buildReport])
6};
If every function in the chain steps aside, the request ends as 204 No Content. A thrown error is caught and returned as the response body rather than crashing the Worker.