Middleware
Add cross-cutting logic to job handlers.
Basic Middleware
const { router, procedure } = init<AppContext>();
const loggedProcedure = procedure.use(async ({ ctx, next }) => {
console.log(`Starting job: ${ctx.jobName}`);
const start = Date.now();
const result = await next();
console.log(`Completed in ${Date.now() - start}ms`);
return result;
});
const jobRouter = router({
"my-job": loggedProcedure
.input({ payload: z.object({ id: z.string() }) })
.task(async ({ input }) => {
// Logging happens automatically
}),
});
Extend Context
const withMetrics = procedure.use(async ({ ctx, next }) => {
return next({
ctx: {
metrics: new MetricsClient(),
},
});
});
// Now ctx.metrics is available in handlers
const jobRouter = router({
"tracked-job": withMetrics
.input({ payload: z.object({ id: z.string() }) })
.task(async ({ ctx }) => {
ctx.metrics.increment("jobs.processed");
}),
});
Chain Middleware
const authedProcedure = procedure
.use(loggingMiddleware)
.use(metricsMiddleware)
.use(rateLimitMiddleware);