Context
Your context holds data that all of your tRPC procedures will have access to, and is a great place to put things like authentication information, or request configuration.
While context is a key feature in tRPC, with NestJS it takes a back sit to the dependency injected Middelwares and Providers.
If you are not sure about what is tRPC context, you can dive into those concepts in their official documentation.
Setting up the context can be done in 3 steps, defining the context class, registering the context with your module, and passing it to the context
option of the TRPCModule.
Defining a Context
To define a new context, we need to create a class that implements TRPCContext
and it's method create()
.
import { Inject, Injectable } from '@nestjs/common';
import { ContextOptions, TRPCContext } from 'nestjs-trpc';
import { InnerContext } from './inner.context';
@Injectable()
export class AppContext implements TRPCContext {
constructor(@Inject(InnerContext) private readonly innerContext: InnerContext){}
async create(opts: ContextOptions): Promise<Record<string, unknown>> {
const contextInner = await this.innerContext.create(opts);
return {
...contextInner,
req: opts.req,
res: opts.res,
};
}
}
In some scenarios it could make sense to split up your context into "inner" and "outer" classes. You can read more in the official tRPC documentation.
Context registration
Similar to NestJS providers, we need to register the context with Nest so that it can perform the injection and type generation.
We do this by editing our module file and adding the context to the providers
array of the @Module()
decorator.
Including in options
Lastly we need to pass the context class to the context
option in our TRPCModule
import definition.
import { Module } from '@nestjs/common';
import { TRPCModule } from 'nestjs-trpc';
import { AppContext } from 'app.context';
@Module({
imports: [
TRPCModule.forRoot({
autoSchemaFile: "/src/@generated",
context: AppContext,
}),
],
})
export class AppModule {}
Now that the context is applied, it will propegate throught all of your middlewares and procedures.
Generated Context
When you apply a context class, a Context
type will be generated from the create()
method return statement.
You can import this type and use throughout your middlewares and procedures from nestjs-trpc/types
, for example:
import { Injectable } from '@nestjs/common';
import { ContextOptions, TRPCContext } from 'nestjs-trpc';
@Injectable()
export class AppContext implements TRPCContext {
create(opts: ContextOptions): Record<string, unknown> {
return {
isContextApplied: true,
};
}
}
Dependency injection
The context class fully supports Dependency Injection. Just as with NestJS providers and controllers,
it is able to inject dependencies that are available within the same module. As usual, this is done through the constructor
.