Docs
Context

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().

app.context.ts
import { Inject, Injectable } from '@nestjs/common';
import { ExpressContextOptions, 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: ExpressContextOptions): 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.

app.module.ts
import { Module } from '@nestjs/common';
import { TRPCModule } from 'nestjs-trpc';
import { AppContext } from 'app.context';
 
@Module({
  imports: [
    TRPCModule.forRoot({
      authoSchemaFile: "/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:

app.context.ts
import { Injectable } from '@nestjs/common';
import { ExpressContextOptions, TRPCContext } from 'nestjs-trpc';
 
@Injectable()
export class AppContext implements TRPCContext {
  create(opts: ExpressContextOptions): 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.