How to query your database using Prisma with NestJS
Learn how to setup a database with Prisma 2.0 and query data using NestJS.
- Authors
- Marc Stammerjohann
- Published at
Prisma is a toolkit for modeling, querying and migrating a database. Prisma 2.0 is rewritten with Rust, read more about the recent release 🎉.
NestJS is a popular typescript server-side application framework. It is heavily influenced by Angular's architecture and enables to create a REST and GraphQL backend.
This guide shows you how to setup a NestJS application querying data from a SQLite database using Prisma 2.0.
TL;DR
Add Prisma to a Nest application and generate a PrismaClient
. Create a Nest PrismaModule
and PrismaService
which extends PrismaClient
and handles the connection using Nest lifecycle events. Inject PrismaService
into REST controllers or GraphQL resolvers to query your data models.
Or use the NestJS Prisma Schematics to automatically setup Prisma in your NestJS application and start defining your Prisma Schema.
nest add nestjs-prisma
Step 1: Start a new NestJS application
Generate a new Nest application or skip to the next step if you follow along with an existing Nest project.
To generate a new Nest application use the nest cli:
npm i -g @nestjs/cli
nest new project-name
Change your directory into the newly created Nest application and open up your preferred IDE.
Step 2: Add Prisma 2.0
Add Prisma 2.0, initialize Prisma Schema and install Prisma Client to your Nest application.
npm install prisma --save-dev
npx prisma init
npm install @prisma/client
Step 3: Update Prisma datasource
In this guide you are connecting to a SQLite database. Update the provider
in the prisma/schema.prisma
to sqlite
and change the url
environment to file:./dev.db
. Prisma Migrate will create a SQLite database at prisma/dev.db
.
The schema.prisma
should look like:
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
generator client {
provider = "prisma-client-js"
}
Step 4: First Prisma model
Now add a model for the database. A simple User
model looks like:
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
Add the above model to schema.prisma
below the generator section.
For more complex models check out Prisma's data modeling definition.
Step 5: Create SQLite database with Migrate
Create your first database migration using the Prisma Migrate. To use Migrate during development use the new command called:
npx prisma migrate dev
This creates a migration.sql
file containing changes you made to the schema.prisma
, updates the database schema and generates a new Prisma Client.
Prisma Migrate has been released as stable with v2.19. Upgrade to the latest Prisma version and you can use the following migrate commands.
# since v2.19
npx prisma migrate <COMMAND>
npx prisma migrate dev
npx prisma migrate reset
npx prisma migrate deploy
npx prisma migrate resolve
npx prisma migrate status
Hassle-Free Database Migrations with Prisma Migrate is highly recommended 🚀 for more information about the stable release of Prisma Migrate.
Step 6: Generate PrismaClient
For each change you make to the data model of schema.prisma
, you need to generate the PrismaClient
again.
Run the following command to generate a new PrismaClient
which contains the CRUD operations for the new User
model:
npx prisma generate
If you run npx prisma migrate dev
the client will be generated automatically after performing the migration.
Step 7: Create a Nest Module and Service for PrismaClient
SQLite database is setup and a User
model is defined with Prisma. Now its time to prepare our NestJS application to query the database using PrismaClient
.
First, generate a Nest module and service called prisma
via the NestJS CLI.
nest generate module prisma
nest generate service prisma
Open the PrismaModule
and add PrismaService
to the exports
list to be available for dependency injection. Add the PrismaModule
to the imports
list of your modules which need to use the PrismaService
.
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Module({
providers: [PrismaService],
exports: [PrismaService] // 👈 export PrismaService for DI
})
export class PrismaModule {}
Open PrismaService
and extend it with the PrismaClient
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient {
constructor() {
super();
}
}
PrismaClient
has two different ways to start a connection to your database: lazy or explicit.
After you run your first query, PrismaClient
automatically creates a connection (lazy) to the database. If needed rapid response after application start, you can explicitly start or stop a connection using $connect()
and $disconnect()
.
Use the Nest Lifecycle Events OnModuleInit
and OnModuleDestroy
to take care of starting explicit the connection for you. Implement OnModuleInit
and OnModuleDestroy
in your PrismaService
.
The PrismaService
with the explicit connection and lifecycle events looks like:
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient
implements OnModuleInit, OnModuleDestroy {
constructor() {
super();
}
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}
Step 8: Query data model
Now you can inject the PrismaService
into any REST controller, GraphQL resolver or service to query our data model. Make sure you add PrismaModule
to the imports
list of the module. Inject it into a controller and create REST endpoints querying and creating User
models.
Note you are directly accessing the type-safe generated API from the PrismaClient
through PrismaService
.
import { Controller, Get, Param, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';
import { PrismaService } from './prisma/prisma.service';
import { CreateUserDto } from './create-user.dto';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly prisma: PrismaService
) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
@Get('users')
async users() {
return await this.prisma.user.findMany();
}
@Get('users/:id')
async user(@Param('id') id: string) {
return await this.prisma.user.findOne({ where: { id: +id } });
}
@Post('user')
async addUser(@Body() createUserDto: CreateUserDto) {
return await this.prisma.user.create({ data: createUserDto });
}
}
Now its time to continue updating your data model, generating PrismaClient
and adding queries to your Nest application.
Checkout nestjs-prisma-starter to get started quickly with Nest and Prisma, if you like it leave a ⭐.
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.