Prisma adapter
Installation
- npm
- yarn
- pnpm
npm install @nestjs-cls/transactional-adapter-prisma
yarn add @nestjs-cls/transactional-adapter-prisma
pnpm add @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,
}),
}),
],
}),
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
@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);
}
}
@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
Since1.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.
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,
}),
}),