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 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.

Table of Contents

Top of Page Comments Related Articles

Related Posts

Find more posts like this one.

Authors
Marc Stammerjohann
October 17, 2022

Codegen REST API types and requests for Angular

Automatic code generation from OpenAPI 3 for Angular
Angular NestJS Read More
Authors
Marc Stammerjohann
July 27, 2022

Downloading files with NestJS

Setup type-safe endpoints for downloading files in your NestJS application.
NestJS Read More
Authors
Marc Stammerjohann
July 08, 2022

Maizzle: Craft beautiful HTML emails with Tailwind CSS

Send beautiful HTML emails via NestJS crafted with Maizzle and Tailwind CSS
Maizzle Tailwind CSS NestJS Read More
Authors
Marc Stammerjohann
November 22, 2021

Prisma Migrate: Deploy Migration with Docker

Perform database migration with Prisma Migrate using Docker
Prisma Docker Read More
Authors
Marc Stammerjohann
August 26, 2021

NestJS: Type-safe File Uploads

Learn how to apply Swagger decorators for type-safe file upload endpoints.
NestJS Read More
Authors
Marc Stammerjohann
July 27, 2022

OpenAPI for your REST APIs in NestJS

Setup Swagger to generate an OpenAPI documentation for your REST endpoints.
NestJS Read More
Authors
Marc Stammerjohann
July 08, 2022

Send Emails with NestJS

Create Email Templates and send them with nodemailer from your Nest application
NestJS Read More
Authors
Marc Stammerjohann
September 18, 2020

DBML generator for Prisma

Visualize Prisma Schema as Entity-Relationship Diagram
Prisma Read More

Sign up for our newsletter

Sign up for our newsletter to stay up to date. Sent every other week.

We care about the protection of your data. Read our Privacy Policy.