The arc model
An arc is Flare's transport-facing capability on the host. HTTP and WebSocket routes share services and config.
An arc is a transport-facing capability registered on FlareHost. Each arc owns how work enters the process (routing, protocol hooks, request-scoped machinery) and how results leave. Business logic stays in FlareService classes and shared config, which the host resolves once and makes available to every arc.
The host exposes these arcs today:
| Arc | Registration surface | Where it runs |
|---|---|---|
| HTTP | host.http | Node, Workers |
| WebSocket | host.ws | Node, Workers |
Why the arc/host split
Section titled “Why the arc/host split”Coupling domain code directly to HTTP means rewriting services when you add a second transport. Flare separates the two:
| Layer | Owns |
|---|---|
| Arc | Transport (paths, protocol middleware, arc-local lifecycle) |
| Host | DI container, config, logger, composition, validation |
A FlareService written for an HTTP controller can be injected from a WebSocket handler without changes. The arc supplies the entry point; the service supplies the logic.
HTTP arc registration
Section titled “HTTP arc registration”The HTTP arc is everything under host.http. That’s where you register inline routes and class-based controllers, global and group-scoped middleware, prefixed route groups, central error mapping, arc-wide CORS, and the arc’s own start and stop hooks.
For the full method surface, see Routing and Host.
WebSocket arc registration
Section titled “WebSocket arc registration”The WebSocket arc lives under host.ws. Register inline handlers with host.ws.route(path) and controller classes with host.ws.controller(path, Cls). Messages are typed with socketContract; parsed upgrade params and inbound messages arrive on scope.input the same way HTTP inline handlers read route, query, and body fields.
See WebSockets for routes, contracts, channels, and connection state.
HTTP request pipeline
Section titled “HTTP request pipeline”For each matched HTTP route, the compiled pipeline runs middleware and the handler in this order:
- Global and group
beforehooks (globals first, then group-local; registration order within each scope). See Middleware for how globals and groups interleave. - Route handler (with contract body parsing immediately before the handler when the route declares a body)
afterhooks (globals first, then group-local; registration order within each scope)finallyhooks (LIFO across the combined middleware list)
Route and query contract values are parsed on the request before any before hook runs so middleware can read typed ctx.req route and query fields. Body contracts run after the before chain and immediately before the handler so auth middleware can reject a request before the body is consumed.
Returning a non-undefined response from before (typically new FlareResponse(...)) skips the handler and all after hooks for that request. finally still runs. See Middleware for short-circuit rules.
Inline handlers read parsed route, query, and body values from scope.input. Controller methods with httpContract use ctx.extract(entry). See HTTP contracts.
build() and the arcs
Section titled “build() and the arcs”host.build() finalizes the whole host in one synchronous call and returns a runtime-specific app (run() on Node, export() on Workers, test() when FLARE_MODE=test). A second call returns the cached app with no extra work.
For the arcs, build() compiles each arc’s routes into per-route pipelines (middleware ordering, router) and validates every arc registration. Arc compile failures, including a route or middleware whose static state token no earlier before() hook provides, throw a plain Error with a descriptive message. For the ordered steps build() runs across the whole host, see What build() does; for how state provisioning is checked across a route’s chain, see Build-time validation.
Callbacks registered with host.http.onStart() and host.http.onStop() stay on the arc; the returned app’s start() / stop() (or async variants) invoke them in registration order alongside singleton service lifecycle.
Related
Section titled “Related”- What build() does: mental model for the compile step
- Build-time validation: validator families
- Dependency injection: scoped vs singleton
- Host: adapters and lifecycle