Skip to main content

Prisma adapter

Installation

npm install @nestjs-cls/transactional-adapter-prisma

Registration

ClsModule.forRoot({
plugins: [
new ClsPluginTransactional({
imports: [
// module in which the PrismaClient is provided
PrismaModule
],
adapter: new TransactionalAdapterPrisma({
// the injection token of the PrismaClient
prismaInjectionToken: PrismaService,
}),
}),
],
}),
important

The prismaInjectionToken is the token under which an instance of PrismaClient provided. Usually, in Nest, this the custom PrismaService class which extends PrismaClient and is exported from a custom module.

Typing & usage

The tx property on the TransactionHost<TransactionalAdapterPrisma> refers to the transactional PrismaClient instance when used in a transactional context. It is the instance that is passed to the prisma.$transaction(( tx ) => { ... }) callback.

Outside of a transactional context, it refers to the regular PrismaClient instance (but is typed as the transactional one).

Example

user.service.ts
@Injectable()
class UserService {
constructor(private readonly userRepository: UserRepository) {}

@Transactional()
async runTransaction() {
// both methods are executed in the same transaction
const user = await this.userRepository.createUser('John');
const foundUser = await this.userRepository.getUserById(user.id);
assert(foundUser.id === user.id);
}
}
user.repository.ts
@Injectable()
class UserRepository {
constructor(
private readonly txHost: TransactionHost<TransactionalAdapterPrisma>,
) {}

async getUserById(id: number) {
// txHost.tx is typed as the transactional PrismaClient
return this.txHost.tx.user.findUnique({ where: { id } });
}

async createUser(name: string) {
return this.txHost.tx.user.create({
data: { name: name, email: `${name}@email.com` },
});
}
}

Custom client type

Since 1.1.0

By default, the adapter assumes that the Prisma client is available as @prisma/client. If you have a different setup, or you use some Prisma client extensions, you can provide a custom type for the client as a generic parameter of the adapter.

TransactionalAdapterPrisma<CustomPrismaClient>;

This type will need to be used whenever you inject the TransactionHost or Transaction

private readonly txHost: TransactionHost<TransactionalAdapterPrisma<CustomPrismaClient>>

Which becomes pretty verbose, so it's recommended to create a custom type alias for the adapter.

important

Please make sure you set up the module with the custom prisma client and not the default one, otherwise you would get a runtime error.

new ClsPluginTransactional({
imports: [
// module in which the PrismaClient is provided
PrismaModule
],
adapter: new TransactionalAdapterPrisma({
// the injection token of the PrismaClient
prismaInjectionToken: CUSTOM_PRISMA_CLIENT_TOKEN,
}),
}),