DEV Community

jacksonPrimo
jacksonPrimo

Posted on

Configurando Prisma ORM no Nestjs usando Singleton Pattern

Configurando o prisma no nestJs seguindo a risca a documentação traz um problema relacionado a abertura de conexões com o banco, ao executar o projeto localmente não há grandes desvantagens nisto, no entanto ao usar um banco online como o caso do ElephantSql ou Supabase que possuem limites de conexões abertas isto vem a se tornar um grande impecilho.

Como consequencia recebemos constantes erros como este:

Error querying the database: db error: FATAL: too many connections for role "qcjoaamjgbnxjx"
Enter fullscreen mode Exit fullscreen mode

Isto ocorre devido a cada modulo abrir uma ou mais conexões e não encerrar ao fim da query. Para resolver, precisariamos ter uma forma de chamar a mesma instancia do prisma todas nossas querys, é aqui que aplicamos o padrão singleton.

Começamos iniciando nosso projeto:

$ npm install -g @nestjs/cli
$ nest new project_name
Enter fullscreen mode Exit fullscreen mode

Em seguida configuramos o prisma:

$ yarn add @prisma/client
$ yarn add prisma --dev
$ yarn prisma init
Enter fullscreen mode Exit fullscreen mode

Agora vamos precisar do nosso modulo singleton para o prisma, para isso iniciaremos um novo service:

$ yarn nest g s modules/services/prisma
Enter fullscreen mode Exit fullscreen mode

Vamos fazer com que este service extenda a classe do prisma e sempre que chamar seu construtor, pegar a mesma instância armazenada em uma variável estática:

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

@Injectable()
export class PrismaService extends PrismaClient {
  private static instance: PrismaClient;

  public static getInstance(): PrismaClient {
    if (!PrismaService.instance) {
      PrismaService.instance = new PrismaClient();
    }

    return PrismaService.instance;
  }
}

Enter fullscreen mode Exit fullscreen mode

Para utilizarmos este service em nossos modulos precisamos adicionar ele dentro dos providers do modulo desejado:

import { Module } from '@nestjs/common';
import { PrismaService } from './services/prisma/prisma.service';

@Module({
  imports: [],
  controllers: [],
  providers: [
    {
      provide: PrismaService,
      useValue: PrismaService.getInstance(),
    },
  ],
})
export class ExempleModule {}
Enter fullscreen mode Exit fullscreen mode

Exemplo de uso:

import { Controller, Get } from '@nestjs/common';
import { PrismaService } from './services/prisma/prisma.service';

@Controller()
export class ExempleController {
  constructor(private readonly prisma: PrismaService) {}

  @Get()
  async exemple(): Promise<any> {
    const newUser = await this.prisma.user.create({ email: '', name: '' });
    return newUser;
  }
}
Enter fullscreen mode Exit fullscreen mode

Referências:
https://engcfraposo.medium.com/aplicando-o-padrão-singleton-no-nestjs-999af3d86c6d

https://docs.nestjs.com/recipes/prisma

Top comments (0)