Dedupe Middleware
Use context to prevent the same middleware from repeating expensive work.
Problem
The same middleware can run more than once during a single call. This often happens when:
- a procedure calls another procedure that both use the same middleware
- you use
.use(authProvider).router(router), and some procedures inrouteralready useauthProvider
WARNING
Repeated middleware work can hurt performance, especially for expensive operations such as opening a database connection.
Solution
Store the computed value in context and reuse it when the middleware runs again.
For example, this middleware loads auth at most once per call:
ts
const authProvider = os
.$context<{ headers: Headers, auth?: { id: string } | undefined, authLoaded?: boolean | undefined }>()
.middleware(async ({ context, next }) => {
// reuse the loaded auth value if it was already loaded
const auth = context.authLoaded
? context.auth
: await loadAuth(context.headers)
return next({ context: { auth, authLoaded: true } })
})You can now apply authProvider multiple times without loading auth again:
ts
const base = os.$context<{ headers: Headers }>()
const foo = base.use(authProvider).handler(({ context }) => 'Hello World')
const bar = base.use(authProvider).handler(({ context }) => {
// Reuse the auth value that is already stored in context.
return call(foo, undefined, { context })
})
// Applying authProvider again does not load auth a second time.
const router = base
.use(authProvider)
.use(({ next }) => {
// Additional middleware logic
return next()
})
.router({
foo,
bar,
})
