Skip to content
brix.v2 stable

Search documentation

70 guides

Documentation menu
Docs / Server and deployment / Server configurationRead Markdown ↗

Server middleware and observability

Add application middleware and state, expose safe errors, and emit bounded request telemetry while Brix preserves infrastructure ordering.

Add middleware and app state

Global business middleware belongs in defineBrixServer; route-specific concerns belong on the route. Brix preserves infrastructure ordering around it.

Extend default serialized app state rather than replacing it. Here, businessContextMiddleware is an application-owned Hono middleware:

export const brixServer = defineBrixServer(brix, {
  middleware: [businessContextMiddleware],
  appState: (c, defaults) => ({
    ...defaults,
    userId: c.req.header("x-user-id"),
  }),
});

Defaults include origin, path, initial query, resolved locale, CSP nonce, production flag, and serialization version. Any custom state sent to islands is browser-visible; never include credentials or private server data.

Handle errors without leaking details

Default 404 and 500 responses are generic JSON. Customize them only when the application needs another public contract. The following examples use an application-owned telemetry adapter:

export const brixServer = defineBrixServer(brix, {
  notFound: (c) => c.json({ error: "Not found" }, 404),
  onError: (error, c) => {
    telemetry.capture(error, c.get("brixRequestId"));
    return c.json({ error: "Request failed" }, 500);
  },
});

Unexpected API handler and response-validation failures reach this policy with their original cause. Do not serialize stack traces, provider responses, environment values, or arbitrary error messages. Deliberate Hono HTTPException responses pass through route handling.

Observe requests safely

Every request accepts a valid x-request-id or gets a generated one, returns it in the response, and exposes c.get("brixRequestId").

export const brixServer = defineBrixServer(brix, {
  env,
  service: (c) => ({
    name: "booking",
    version: c.env.VERSION,
    environment: c.env.STAGE,
  }),
  observability: {
    eventTimeoutMs: 1_000,
    onEvent: (event) => telemetry.emit(event),
  },
});

Events cover request start, end, and error with method, pathname, request ID, timing, status, incoming traceparent, and service metadata. They omit query strings, bodies, and arbitrary headers. Redact dynamic paths and error details before export. Adapter failures are logged and do not fail requests; delivery waits at most one second by default.