Skip to content

Latest commit

 

History

History
226 lines (217 loc) · 6.14 KB

1.integration-prisma.md

File metadata and controls

226 lines (217 loc) · 6.14 KB

Functional-NestJS

Functional Programming with NestJS, Prisma.
immutable, pure, stateless.

1. Introduction

A production ready typescript backend repository utilized those libraries:

2. Setup and integraion Prisma with nestJS

2.1. Content Goal.

  • Integration Prisma with NestJS.
  • Generate Prisma Module and using DI.
  • First My Database Query

2.1. Initialize prisma

Adding Prisma to the Nest project.
First, install prisma CLI in dev dependency, @prisma/client in dependency.
Init command creates new ```prisma`` directory.

Command

yarn add -D prisma
npx prisma init
yarn add @prisma/client

2.2. First prisma migration

Use this prisma schema example.
schema.prisma file is declared a PSL(Prisma Schema Language). For this repository, you'll create a community model.
Adding the community model in schema.prisma.

model User {
 id        Int      @id @default(autoincrement())
 createdAt DateTime @default(now())
 email     String   @unique
 name      String?
 role      Role     @default(USER)
 posts     Post[]
}

model Post {
 id        Int      @id @default(autoincrement())
 createdAt DateTime @default(now())
 updatedAt DateTime @updatedAt
 published Boolean  @default(false)
 title     String   @db.VarChar(255)
 author    User?    @relation(fields: [authorId], references: [id])
 authorId  Int?
}

enum Role {
 USER
 ADMIN
}

Migration your Postgres database file for your dev environment using Prisma Migrate.
Use the prisma migrate dev command to complete your first prisma migration.

Command

npx prisma migrate dev

Then, You maybe have new directory (prisma/migrations) for migration history.

2.3. Create a nest module,service with prisma.

Prisma set up complete and can access database.
To integration prisma into nestJS, generate a module and service used prismaClient.

Command

nest generate module prisma
nest generate service prisma

Q1. How to use Prisma Service inside Prisma Module in another module ?
A1. Add Prisma Service to module export list and DI Prisma Module in other module.
If use @Global() decorator for Prisma Module, Only import the Prisma Module once.

Prisma Module

// src/prisma/prisma.module.ts
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Global() // generate Global Module
@Module({
 providers: [PrismaService],
 exports: [PrismaService], // for DI
})
export class PrismaModule {}

Prisma Service

// src/prisma/prisma.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient {
 constructor() {
   super();
 }
}

2.4. Create a user module,service.

Command

nest generate module user
nest generate service user
nest generate controller user

Use ```Prisma Service`` in user repository.

src/user/user.repository.ts

import { Injectable } from '@nestjs/common';
import { PrismaService } from '@prismaModule/prisma.service';

@Injectable()
export class UserRepository {
   constructor(private prisma: PrismaService) {}

   getUsers() {
       return this.prisma.user.findMany();
   }
}

2.5. Implement explicit prisma connect

PrismaClient has two connect database mode.

  • lazy : connect for the first request
  • explicit : call prisma.$connect()
    assignment
  • Implement expllict prisma connect for nestJS LifeCycle OnModuleInit, OnModuleDestory.
  • Set PrismaClient log level.

solution

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService
   extends PrismaClient
   implements OnModuleInit, OnModuleDestroy
{
   constructor() {
       super({
           log: [
               { emit: 'stdout', level: 'query' },
               { emit: 'stdout', level: 'error' },
           ],
       });
   }

   async onModuleInit() {
       await this.$connect();
   }

   async onModuleDestroy() {
       await this.$disconnect();
   }
}

3. Advanced Education

3.1.Seeding Databae using prisma db seed

  1. Add prisma command in package.json.

command

"prisma":{
 "seed": "ts-node prisma/seed/index.ts"
},
  1. Add seed Data to the prisma/seed directory using Prisma.validator.

code

import { Prisma } from '@prisma/client';

export const users = Prisma.validator<Prisma.UserCreateManyArgs>()({
   data: [
       {
           name: 'y0on2q',
           email: '[email protected]',
           active: 1,
           role: 'ADMIN',
       },
       {
           name: 'currying',
           email: '[email protected]',
           active: 0,
           role: 'USER',
       },
       {
           name: 'monad',
           email: 'monad@monad,com',
           active: 1,
           role: 'USER',
       },
   ],
});
  1. Add main seed file to the prisma/seed directory.

code

import { PrismaClient } from '@prisma/client';
import { users } from './user.seed';

const prisma = new PrismaClient();

const main = async () => {
   await prisma.user.createMany(users);
};

main()
   .catch(e => {
       console.error(e);
       process.exit(1);
   })
   .finally(async () => {
       await prisma.$disconnect();
   });
  1. Run Prisma db seed command

command
npx prisma db seed

  1. Run Prisma studio and view seeding data.

command
npx prisma studio