Runtime Features
Middleware, auth injection, and runtime inspection for serve({ queries }).
Runtime Features
Beyond routing, serve({ queries }) gives you a runtime surface you can extend and inspect.
api.use(middleware)
Use middleware to run shared logic around every request:
const timingMiddleware = async (ctx, next) => {
const start = Date.now();
const result = await next();
console.log('durationMs', Date.now() - start);
return result;
};
api.use(timingMiddleware);Use middleware for:
- rate limiting
- logging
- extra validation
- request shaping
api.useAuth(strategy)
Add an auth strategy to the runtime after creation:
api.useAuth(async ({ request }) => {
const token = request.headers.authorization;
if (!token) return null;
return verifyToken(token);
});This is useful when the runtime is created before auth wiring is available.
api.describe()
Use api.describe() to inspect the runtime shape programmatically:
const description = api.describe();
console.log(description.queries);description.queries lists every registered endpoint, including auto-generated semantic ones. Metric endpoints appear under their metric name and dataset endpoints under the dataset:<name> key, each with its method, path, auth requirements, and contract metadata.
This is useful for:
- internal tooling
- AI and agent surfaces
- generated clients
- runtime introspection in tests
Semantic endpoints share the runtime
metrics and datasets registered with serve({ ... }) flow through the same runtime as queries. Global middleware added with api.use(...) wraps them, api.describe() reports them, and api.run('<metric>') / api.run('dataset:<name>') executes them in-process.
To attach middleware to a single semantic endpoint, use the per-entry middlewares option instead of api.use(...):
export const api = serve({
queryBuilder: db,
metrics: {
revenue: {
metric: revenue,
middlewares: [auditLog],
},
},
});Observability belongs one layer over
Hooks, query logging, and slow query detection are part of the same runtime surface, but they are covered in Observability to keep this page focused on extension points.
Use that page for:
hooks.onRequestStarthooks.onRequestEndhooks.onAuthFailurehooks.onAuthorizationFailurehooks.onErrorqueryLoggingslowQueryThreshold