Overview
Per-request HTTP state with flareState tokens, middleware provides, and build-time provisioning checks.
Per-request HTTP state is typed data on FlareHttpContext for one request. You create state tokens with flareState(), write values in middleware before() hooks, read them in handlers via ctx.state, and declare dependencies so HTTP compile verifies an upstream middleware provides each token.
This is separate from host.state, which is the host lifecycle state ("starting" | "ready" | "draining" | "stopped").
How it fits the pipeline
Section titled “How it fits the pipeline”- Middleware
before()callsctx.state.set(token, value)for tokens inprovides. - Route handlers read with
ctx.state.require(token)orctx.state.get(token). - At
build(), Flare walks each route’s middleware chain and fails when a declared token has no upstreambefore()provider.
Values are deep-frozen on write. Handlers get snapshots, not live mutable references.
The alternative this replaces is the mutable bag: a req.user patched on by whichever middleware happened to run, read through a cast. Nothing ties the writer to the reader there, so “did auth run before this handler” is a convention enforced by code review, and the failure mode is undefined deep in a handler, on the first request that takes an unusual path. The token graph turns each of those conventions into a checked declaration: a reader states what it needs, exactly one provider may exist, values are snapshots rather than shared mutable state, and the wiring mistake fails build() naming the token instead of failing a user.
Pages in this section
Section titled “Pages in this section”| Page | Covers |
|---|---|
| Declaring state | flareState(), withDefault, from, withLogging |
| Reading state | get, set, require |
| Middleware that provides state | Auth pattern with short-circuit 401 |
| State and logging | requestId and log context on HTTP requests |
| Build-time state validation | Cycles, dead middleware, missing providers |
Quick example
Section titled “Quick example”import { FlareHost, FlareResponse, MiddlewareBase, flareState } from "@flare-ts/core";import { node } from "@flare-ts/core/node";
const AuthUser = flareState<{ id: string }>("AuthUser");
class AuthMiddleware extends MiddlewareBase { public static override deps = []; public static override state = []; public static override provides = [AuthUser];
before() { this.ctx.state.set(AuthUser, { id: "u1" }); }}
const host = new FlareHost(node);host.http.use(AuthMiddleware);
host.http.get("/me", { state: [AuthUser] }, (ctx) => { return new FlareResponse(200, ctx.state.require(AuthUser));});
const app = host.build();app.run();Error handlers
Section titled “Error handlers”Error handlers are not part of the state wiring graph. handle(err, context) receives HttpErrorContext, not FlareHttpContext. Pass request data through FlareError.detail or an injected service instead.
Related
Section titled “Related”- Middleware
- Dependency injection
- The arc model: state provisioning at compile