How to use Prisma in NestJS
The ultimate tutorial to get started with Prisma and NestJs.
Posted August 18, 2022
Learn NestJs the right way
Skyrocket your NestJs skills to the top
- NestJs Architecture
- Sessions
- Caching
- Pagination
- Scaling with Redis
- Unit Testing
- RBAC & CronJobs
With the advent of modern web development, even SQL and traditional ORMs are not protected from disruption. Prisma is a next-generation ORM that has been taking backend by storm.
What is Prisma
Prisma is a next-generation ORM for NodeJs that works flawlessly with Typescript. It is somewhere in between a traditional ORM and a query builder. The main selling point is that Prisma can automatically generate types when the database model changes. This is a game changer! No need to maintain classes that map to data or write complex SQL.
Prisma and NestJs are probably my favourite backend technologies in the NodeJs ecosystem, and I am excited to show you how to use them together!
Installation & Setup
Once your NestJs project is set up, you must install the Prisma CLI and the Prisma client.
npm i -D prisma
npm i @prisma/client
Once the installation is complete, you need to initialize the Prisma initial configuration.
npx prisma init
This should create a Prisma folder and a .env file.
If you open the .env file, you will see a Postgres connection string.
DATABASE_URL=postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public
In this tutorial, we will use SQLite. So rename the connection string to cats.sqlite.
DATABASE_URL="file:./cats.sqlite"
Create Prisma Cat Model
If you open the Prisma folder, you will find a schema file. This schema stores all your database models. Database models represent your database's tables with their values.
In this tutorial, we are going to create a Cat table with fields:
- id
- name
- breed
- createdAt
- updatedAt
Open your prisma.schema file and fill it with the model below
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql" // the database we use
url = env("DATABASE_URL") // database connectiong string
}
model Cat {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String
breed String
@@map("cat")
}
Create Prisma Migrations
To create the table "Cat", we must create migrations and apply them to the database. When you develop, this can be easily done with
npx prisma migrate dev --name add_cat_table
If you omit the "name" argument, Prisma will prompt you to enter one. Every migration is timestamped and suffixed with the name you give it.
.
├── migrations
│ ├── 20220801004112_init
│ │ └── migration.sql
│ └── migration_lock.toml
└── schema.prisma
When you create migrations, Prisma also runs the generate command that generates typescript types.
NB: This command can also be individually executed with
npx prisma generate
This way, you can use the model types in your project. You can find the generated types in node_modules/.prisma/index.d.ts
export type Cat = {
id: number
createdAt: Date
updatedAt: Date
name: string
breed: string
}
Create Prisma Service
The easiest way to use Prisma in our NestJs application is to include it in a service/provider that can be injected as a dependency injection.
.
├── app.module.ts
├── main.ts
└── prisma
├── prisma.module.ts
└── prisma.service.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
NB: We make the PrismaModule global. This way, the PrismaService can be easily used in all our application
Create Cat Service
We will create two functions to demonstrate that our connection to Prisma works.
- addCat: will create a can in the database
- getCat: will get and return a cat by its id
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
@Injectable()
export class CatService {
constructor(private prisma: PrismaService) {}
async addCat(name: string, breed: string) {
const cat = await this.prisma.cat.create({
data: {
name,
breed,
},
});
return cat;
}
async getCat(catId: number) {
const cat = await this.prisma.cat.findUnique({
where: {
id: catId,
},
});
return cat;
}
}
Configure NestJs Repl
Starting from NestJs v9, we can use the REPL to programmatically call a function in our app without writing custom scripts or tests.
To use the REPL, you first need to create the REPL bootstrap file.
.
├── app.module.ts
├── cat
│ ├── cat.module.ts
│ └── cat.service.ts
├── main.ts
├── prisma
│ ├── prisma.module.ts
│ └── prisma.service.ts
└── repl.ts
import { repl } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
await repl(AppModule);
}
bootstrap();
To run start our app with repl you can run the following script
npm run start:dev -- --entryFile repl
The terminal should start with no errors
[14:13:32] Starting compilation in watch mode...
[14:13:33] Found 0 errors. Watching for file changes.
[Nest] 13365 - 18/08/2022, 14:13:33 LOG [NestFactory] Starting Nest application...
[Nest] 13365 - 18/08/2022, 14:13:33 LOG [InstanceLoader] AppModule dependencies initialized
[Nest] 13365 - 18/08/2022, 14:13:33 LOG [InstanceLoader] PrismaModule dependencies initialized
[Nest] 13365 - 18/08/2022, 14:13:33 LOG [InstanceLoader] CatModule dependencies initialized
[Nest] 13365 - 18/08/2022, 14:13:33 LOG REPL initialized
>
Test with NestJs REPL
Create a cat record
While you are in REPL you can use the debug() function to get an understand of the available functions you have at your disposal. The syntax is similar to jQuery
Now call debug() function to see what classes you can call
> debug()
AppModule:
PrismaModule:
- providers:
◻ PrismaService
CatModule:
- providers:
◻ CatService
>
You also have access to the global level await. No need to wrap the call in an async function.
> await $(CatService).getCat(1)
null
>
Let's create a cat record by calling the addCat() function
> await $(CatService).addCat("Salem", "American Shorthair")
{
id: 1,
createdAt: 2022-08-18T13:25:07.092Z,
updatedAt: 2022-08-18T13:25:07.093Z,
name: 'Salem',
breed: 'American Shorthair'
}
>
Awesome! The record has been created in the database.
Get the cat record
Now let's get this record from the SQLite database by calling getCat() function.
> await $(CatService).getCat(1)
{
id: 1,
createdAt: 2022-08-18T13:25:07.092Z,
updatedAt: 2022-08-18T13:25:07.093Z,
name: 'Salem',
breed: 'American Shorthair'
}
Awesome!
Summary
In this tutorial we have seen how to:
- Use Prisma with NestJs and SQLite
- Create Prisma models
- Run Prisma migrations
- Integrate Prisma with NestJs as a provider
- Use the NestJs REPL to test our application
Learn NestJs the right way
Skyrocket your NestJs skills to the top
- NestJs Architecture
- Sessions
- Caching
- Pagination
- Scaling with Redis
- Unit Testing
- RBAC & CronJobs