Context
Use oRPC context for type-safe dependency injection, providing initial context explicitly or injecting values through middleware.
Initial Context
Use initial context for values that come from the environment. Declare it with .$context, then provide it when executing the procedure:
const const base: Builder<{
env: {
DB_URL: string;
};
} & object, Record<never, never>>
base = const os: Builder<DefaultInitialContext & object, Record<never, never>>The oRPC procedure builder. Chain methods like `.input`, `.use`, and `.handler`
to define procedures, then compose them into routers.os.Builder<DefaultInitialContext & object, Record<never, never>>.$context<{
env: {
DB_URL: string;
};
}>(): Builder<{
env: {
DB_URL: string;
};
} & object, Record<never, never>>
Declares the initial context type that must be provided when executing
procedures built from this builder.$context<{ env: {
DB_URL: string;
}
env: { type DB_URL: stringDB_URL: string } }>()
export const const getting: DecoratedProcedure<{
env: {
DB_URL: string;
};
} & object, object, InitialInputSchema, Schema<void>, Record<never, never>, never>
getting = const base: Builder<{
env: {
DB_URL: string;
};
} & object, Record<never, never>>
base
.Builder<{ env: { DB_URL: string; }; } & object, Record<never, never>>.handler<void>(handler: ProcedureHandler<{
env: {
DB_URL: string;
};
} & object, unknown, void, ORPCErrorConstructorMap<Record<never, never>>>): DecoratedProcedure<{
env: {
DB_URL: string;
};
} & object, object, InitialInputSchema, Schema<void>, Record<never, never>, never>
Defines the function that implements the procedure and completes the
chain, returning a callable procedure.handler(async ({ context: {
env: {
DB_URL: string;
};
} & object
context }) => {
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log(context: {
env: {
DB_URL: string;
};
} & object
context.env: {
DB_URL: string;
}
env)
})
Default Initial Context
To avoid repeating .$context declarations, you can define a default initial context type globally.
declare module '@orpc/server' {
export interface DefaultInitialContext {
env: { DB_URL: string }
}
}
Injected Context
Injected context is injected at runtime through middleware:
const const base: BuilderWithMiddlewares<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, Record<never, never>>
base = const os: Builder<DefaultInitialContext & object, Record<never, never>>The oRPC procedure builder. Chain methods like `.input`, `.use`, and `.handler`
to define procedures, then compose them into routers.os.Builder<DefaultInitialContext & object, Record<never, never>>.use<{
env: {
DB_URL: string;
};
}, DefaultInitialContext & object, Record<never, never>>(middleware: Middleware<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, unknown, unknown, Record<never, never>>): BuilderWithMiddlewares<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, Record<never, never>>
Applies a middleware that runs before the handler of every procedure
built from this builder.use(async ({ next: MiddlewareNext<unknown>Invoke to continue the middleware chain.next }) => next: MiddlewareNext
<{
env: {
DB_URL: string;
};
}>(options: {
context: {
env: {
DB_URL: string;
};
};
}) => MiddlewareResult<{
env: {
DB_URL: string;
};
}, unknown>
Invoke to continue the middleware chain.next({
context: {
env: {
DB_URL: string;
};
}
context: {
env: {
DB_URL: string;
}
env: { type DB_URL: stringDB_URL: const env: {
DB_URL: string;
}
env.type DB_URL: stringDB_URL },
},
}))
export const const getting: DecoratedProcedure<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, InitialInputSchema, Schema<void>, Record<never, never>, never>
getting = const base: BuilderWithMiddlewares<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, Record<never, never>>
base.BuilderWithMiddlewares<DefaultInitialContext & object, { env: { DB_URL: string; }; }, Record<never, never>>['handler']<void>(handler: ProcedureHandler<Omit<DefaultInitialContext & object, "env"> & {
env: {
DB_URL: string;
};
}, unknown, void, ORPCErrorConstructorMap<Record<never, never>>>): DecoratedProcedure<DefaultInitialContext & object, {
env: {
DB_URL: string;
};
}, InitialInputSchema, Schema<void>, Record<never, never>, never>
Defines the function that implements the procedure and completes the
chain, returning a callable procedure.handler(async ({ context: Omit<DefaultInitialContext & object, "env"> & {
env: {
DB_URL: string;
};
}
context }) => {
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log(context: Omit<DefaultInitialContext & object, "env"> & {
env: {
DB_URL: string;
};
}
context.env: {
DB_URL: string;
}
env)
})
Combining Initial and Injected Context
In many cases, you will use both. Use initial context for environment-specific values, such as database URLs, and injected context for runtime data, such as authenticated users.
const const base: Builder<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, Record<never, never>>
base = const os: Builder<DefaultInitialContext & object, Record<never, never>>The oRPC procedure builder. Chain methods like `.input`, `.use`, and `.handler`
to define procedures, then compose them into routers.os.Builder<DefaultInitialContext & object, Record<never, never>>.$context<{
headers: Headers;
env: {
JWT_SECRET: string;
};
}>(): Builder<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, Record<never, never>>
Declares the initial context type that must be provided when executing
procedures built from this builder.$context<{ headers: Headersheaders: Headers, env: {
JWT_SECRET: string;
}
env: { type JWT_SECRET: stringJWT_SECRET: string } }>()
const const requireAuth: DecoratedMiddleware<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, unknown, any, Record<never, never>>
requireAuth = const base: Builder<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, Record<never, never>>
base.Builder<{ headers: Headers; env: { JWT_SECRET: string; }; } & object, Record<never, never>>.middleware<{
user: {
userId: number;
};
}, unknown, any>(middleware: Middleware<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, unknown, any, Record<never, never>>): DecoratedMiddleware<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, unknown, any, Record<never, never>>
Creates a standalone middleware that can be composed and applied to any
compatible builder or procedure with `.use`.middleware(async ({ context: {
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object
context, next: MiddlewareNext<any>Invoke to continue the middleware chain.next }) => {
const const user: {
userId: number;
} | null
user = function parseJWT(token: string | undefined, secret: string): {
userId: number;
} | null
parseJWT(
context: {
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object
context.headers: Headersheaders.Headers.get(name: string): string | nullThe **`get()`** method of the Headers interface returns a byte string of all the values of a header within a Headers object with a given name. If the requested header doesn't exist in the Headers object, it returns null.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/get)get('authorization')?.String.split(separator: string | RegExp, limit?: number): string[] (+1 overload)Split a string into substrings using the specified separator and return them as an array.split(' ')[1],
context: {
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object
context.env: {
JWT_SECRET: string;
}
env.type JWT_SECRET: stringJWT_SECRET
)
if (!const user: {
userId: number;
} | null
user) {
throw new new ORPCError<"UNAUTHORIZED", unknown>(code: "UNAUTHORIZED", options?: ORPCErrorOptions<unknown> | undefined): ORPCError<"UNAUTHORIZED", unknown>Typed error carrying a `code`, a `message`, and optional `data`.
Throw it from handlers or middleware to produce typed error responses on the client.ORPCError('UNAUTHORIZED')
}
return next: MiddlewareNext
<{
user: {
userId: number;
};
}>(options: {
context: {
user: {
userId: number;
};
};
}) => MiddlewareResult<{
user: {
userId: number;
};
}, any>
Invoke to continue the middleware chain.next({ context: {
user: {
userId: number;
};
}
context: { user: {
userId: number;
}
user } })
})
const const getting: DecoratedProcedure<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, InitialInputSchema, Schema<void>, Record<never, never>, never>
getting = const base: Builder<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, Record<never, never>>
base
.Builder<{ headers: Headers; env: { JWT_SECRET: string; }; } & object, Record<never, never>>.use<{
user: {
userId: number;
};
}, {
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, Record<never, never>>(middleware: Middleware<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, unknown, unknown, Record<never, never>>): BuilderWithMiddlewares<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, Record<never, never>>
Applies a middleware that runs before the handler of every procedure
built from this builder.use(const requireAuth: DecoratedMiddleware<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, unknown, any, Record<never, never>>
requireAuth)
.BuilderWithMiddlewares<{ headers: Headers; env: { JWT_SECRET: string; }; } & object, { user: { userId: number; }; }, Record<never, never>>['handler']<void>(handler: ProcedureHandler<Omit<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, "user"> & {
user: {
userId: number;
};
}, unknown, void, ORPCErrorConstructorMap<Record<never, never>>>): DecoratedProcedure<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, {
user: {
userId: number;
};
}, InitialInputSchema, Schema<void>, Record<never, never>, never>
Defines the function that implements the procedure and completes the
chain, returning a callable procedure.handler(async ({ context: Omit<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, "user"> & {
user: {
userId: number;
};
}
context }) => {
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log(context: Omit<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, "user"> & {
user: {
userId: number;
};
}
context.env: {
JWT_SECRET: string;
}
env)
var console: Consoleconsole.Console.log(...data: any[]): voidThe **`console.log()`** static method outputs a message to the console.
[MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)log(context: Omit<{
headers: Headers;
env: {
JWT_SECRET: string;
};
} & object, "user"> & {
user: {
userId: number;
};
}
context.user: {
userId: number;
}
user)
})