Introducing NestJS Prisma Library and Schematics
Library and schematics to add Prisma integration to a NestJS application
- Authors
- Marc Stammerjohann
- Published at
Until now, adding Prisma to a NestJS application requires a few manual steps - installing @prisma/cli and @prisma/client, creating a PrismaService
and (eventually) adding a Dockerfile
.
We are excited to release nestjs-prisma - a library with build-in PrismaService
, PrismaClientExceptionFilter
, loggingMiddleware
and a set of schematics to perform automatically all steps necessary to add Prisma to your NestJS application.
Schematics
All you need to do is run the following command in your Nest app:
nest add nestjs-prisma
Library
Since version 0.6.0 the package nestjs-prisma
is also a library providing PrismaService
, PrismaModule
and PrismaClientExceptionFilter
(0.13.0).
PrismaModule and PrismaService
Add PrismaModule
to the imports section in your AppModule
or any other modules to gain access to PrismaService
.
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma';
@Module({
imports: [PrismaModule.forRoot()],
})
export class AppModule {}
PrismaModule
allows to be used globally and to pass options to the PrismaClient
.
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma';
@Module({
imports: [
PrismaModule.forRoot({
isGlobal: true,
prismaServiceOptions: {
prismaOptions: { log: ['info'] },
explicitConnect: true,
},
}),
],
})
export class AppModule {}
Additionally, PrismaModule
provides a forRootAsync
to pass options asynchronously. One option is to use a factory function:
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma';
@Module({
imports: [
PrismaModule.forRootAsync({
isGlobal: true,
useFactory: () => ({
prismaOptions: {
log: ['info', 'query'],
},
explicitConnect: false,
}),
}),
],
})
export class AppModule {}
You can inject dependencies such as ConfigModule
to load options from .env files.
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { PrismaModule } from 'nestjs-prisma';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
PrismaModule.forRootAsync({
isGlobal: true,
useFactory: async (configService: ConfigService) => {
return {
prismaOptions: {
log: [configService.get('log')],
datasources: {
db: {
url: configService.get('DATABASE_URL'),
},
},
},
explicitConnect: configService.get('explicit'),
};
},
inject: [ConfigService],
}),
],
})
export class AppModule {}
Alternatively, you can use a class instead of a factory:
import { Module } from '@nestjs/common';
import { PrismaModule } from 'nestjs-prisma';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
PrismaModule.forRootAsync({
isGlobal: true,
useClass: PrismaConfigService,
}),
],
})
export class AppModule {}
Create the PrismaConfigService
and extend it with the PrismaOptionsFactory
import { Injectable } from '@nestjs/common';
import { PrismaOptionsFactory, PrismaServiceOptions } from '.nestjs-prisma';
@Injectable()
export class PrismaConfigService implements PrismaOptionsFactory {
constructor() {
// TODO inject any other service here like the `ConfigService`
}
createPrismaOptions(): PrismaServiceOptions | Promise<PrismaServiceOptions> {
return {
prismaOptions: {
log: ['info', 'query'],
},
explicitConnect: true,
};
}
}
PrismaClientExceptionFilter
nestjs-prisma
provides a PrismaClientExceptionFilter
to catch unhandled PrismaClientKnownRequestError and returning different status codes instead of 500 Internal server error
.
To use the filter you have the following two options.
- Instantiate the filter in your
main.ts
and pass theHttpAdapterHost
import { ValidationPipe } from '@nestjs/common';
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { PrismaClientExceptionFilter } from 'nestjs-prisma';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new PrismaClientExceptionFilter(httpAdapter));
await app.listen(3000);
}
bootstrap();
- Use
APP_FILTER
token in any module
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { PrismaClientExceptionFilter } from 'nestjs-prisma';
@Module({
providers: [
{
provide: APP_FILTER,
useClass: PrismaClientExceptionFilter,
},
],
})
export class AppModule {}
Additional Options
Do you need more options? I got you covered, you can go a step further and specify a Prisma version if you like:
nest add nestjs-prisma --prismaVersion 2.4.1
Or go crazy by adding a Dockerfile
for your Nest app and a docker-compose.yaml
with a PostgreSQL database.
nest add nestjs-prisma --addDocker
Check out all options and give it a try with your Nest app.
Sponsor us
Did you find this post useful? We at notiz.dev write about our experiences developing Apps, Websites and APIs and develop Open Source tools. Your support would mean a lot to us 🙏. Receive a reward by sponsoring us on Patreon or start with a one-time donation on GitHub Sponsors.