Skip to content

Inline middleware

Register one-off before, after, and finally hooks with builder callbacks and HttpMiddlewareOptions on host.http.

AI generated, pending review Updated 10 days ago · Flare 0.3

For one-off hooks, register callbacks on the HTTP arc or inside a route group:

import { FlareHost, FlareResponse, flareState, Logger } from "@flare-ts/core";
import { node } from "@flare-ts/core/node";
const AuthUser = flareState<{ id: string }>("AuthUser");
const host = new FlareHost(node);
host.http.before({ provides: [AuthUser] }, (ctx) => {
ctx.state.set(AuthUser, { id: "u1" });
});
host.http.after((_ctx, result) => {
if (result instanceof FlareResponse) {
result.headers["x-flare-version"] = "1.0";
}
});
host.http.finally({ inject: { log: Logger } }, (_ctx, _result, scope) => {
scope.log.debug("finished");
});
host.http.get("/me", { state: [AuthUser] }, (ctx) => {
return new FlareResponse(200, ctx.state.require(AuthUser));
});
const app = host.build();
app.run();
MethodSignature
before(handler)(ctx, scope) => override
before(options, handler)Same with HttpMiddlewareOptions
after(handler)(ctx, result, scope) => override
after(options, handler)Same with options
finally(handler)(ctx, result, scope) => override
finally(options, handler)Same with options

All hooks may be async. Return undefined or void to continue the pipeline.

OptionPurpose
injectNamed map { name: Token } for scope.name
stateState tokens this hook reads via ctx.state
providesState tokens written in a before hook
nameDisplay name for the synthetic middleware wrapper

A route or middleware that declares state: [Token] compiles only when an upstream before hook provides each token. Middleware that only implements after or finally does not satisfy route state, even if provides is set. Put token writes in before().

import { FlareHost, FlareResponse } from "@flare-ts/core";
import { node } from "@flare-ts/core/node";
const host = new FlareHost(node);
host.http.before((ctx) => {
if (ctx.req.headers.get("x-blocked") === "1") {
return new FlareResponse(429, { error: "rate limited" });
}
});
host.http.get("/ok", () => new FlareResponse(200, { ok: true }));
const app = host.build();
app.run();

Register inside host.http.group:

host.http.group("/api", (g) => {
g.before((ctx) => { /* only /api/* routes */ });
g.get("/status", () => new FlareResponse(200, { ok: true }));
return g.register();
});