In this short article, I show my approach to setting up and using a PrismaModule in NestJs.
This article assumes that you already have Prisma already setup and ready to go within a NestJs project.
Prisma Module
Create a Prisma module and service. These will be used to access Prisma in the rest of your application.
// src/prisma/prisma.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { PrismaService } from './prisma.service';
@Module({
// Assumes that env variables are retrieved
// from the config module.
imports: [ConfigModule],
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
// src/prisma/prisma.service.ts
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Prisma, PrismaClient } from '@prisma/client';
import { EnvironmentVariables } from '../config/types';
/**
* Extension of the PrismaClient for use with NestJs.
*/
@Injectable()
export class PrismaService extends PrismaClient
implements OnModuleInit, OnModuleDestroy {
constructor(private configService: ConfigService<EnvironmentVariables>) {
/**
* Get the database url from environmental variables and pass it in.
*/
super({
datasources: {
db: {
url: configService.get('DATABASE_URL'),
},
},
});
}
/**
* Connect to the database when the module is initialized.
*/
async onModuleInit(): Promise<void> {
await this.$connect();
}
/**
* Disconnect from the database when the application is shutting down.
*/
async onModuleDestroy(): Promise<void> {
await this.$disconnect();
}
/**
* A utility function used to clear all database rows for testing.
*/
clearDatabase() {
const modelNames = Prisma.dmmf.datamodel.models.map(model => model.name);
return Promise.all(
modelNames.map(modelName =>
this[modelName[0].toLowerCase() + modelName.slice(1)].deleteMany(),
),
);
}
}
Using the Prisma Service
When the application starts up, the PrismaService
will attempt to connect to the database automatically.
To create something like a TodoService
, import the PrismaModule
, and use the PrismaService
to create the access layer.
// src/todo/todo.service.ts
//... imports
@Injectable()
export class TodoService {
private logger = new Logger(TodoService.name);
constructor(private prismaService: PrismaService) {}
/**
* The easiest way to get started is to simply expose
* the desired methods on the model's service.
*/
public create = this.prismaService.todo.create;
public findFirst = this.prismaService.todo.findFirst;
public findMany = this.prismaService.todo.findMany;
public update = this.prismaService.todo.update;
public delete = this.prismaService.todo.delete;
public count = this.prismaService.todo.count;
/**
* You can get access to the types to reuse them in custom function's
* arguments.
*/
public specialCreate(data: Prisma.TodoCreateArgs['data']) {
return this.prismaService.planner.create({
data: {
text: 'do something',
...data,
},
});
}
}
Conclusion
From there, you should be able to begin to build out your NestJs application using Prisma.
If you're interested in a more longform explanation with more examples, please let me know in the comments!
Top comments (0)