Context in oRPC
oRPC's context mechanism provides a type-safe dependency injection pattern. It lets you supply required dependencies either explicitly or dynamically through middleware. There are two types:
- Initial Context: Provided explicitly when invoking a procedure.
- Execution Context: Generated during procedure execution, typically by middleware.
Initial Context
Initial context is used to define required dependencies (usually environment-specific) that must be passed when calling a procedure.
const = .<{ : Headers, : { : string } }>()
const =
.(async ({ }) => {
.(.)
})
export const = { }When calling that requires initial context, pass it explicitly:
import { } from '@orpc/server/fetch'
const = new ()
export default function (: Request) {
.(, {
: { // <-- you must pass initial context here
: .,
: {
: '***'
}
}
})
}Execution context
Execution context is computed during the process lifecycle, usually via middleware. It can be used independently or combined with initial context.
import { , } from 'next/headers'
const = .(async ({ }) => ({
: {
: await (),
: await (),
},
}))
const = .(async ({ }) => {
..('key', 'value')
})
export const = { }When using execution context, you don't need to pass any context manually:
import { } from '@orpc/server/fetch'
const = new ()
export default function (: Request) {
.() // <-- no need to pass anything more
}Combining Initial and Execution Context
Often you need both static and dynamic dependencies. Use initial context for environment-specific values (e.g., database URLs) and middleware (execution context) for runtime data (e.g., user authentication).
const = .<{ : Headers, : { : string } }>()
const = .(async ({ , }) => {
const = (..('authorization')?.(' ')[1])
if () {
return ({ : { } })
}
throw new ('UNAUTHORIZED')
})
const = .(async ({ , }) => {
const = new (..)
try {
await .()
return ({ : { : } })
}
finally {
await .()
}
})
const =
.()
.()
.(async ({ }) => {
.(.)
.(.)
})
