skip to Main Content

Are there any more elegant ways to use Drizzle ORM in Nest.js besides the providers? For example like in Prisma with PrismaService, all I found is only with providers like:

import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as schema from './schema';

export const PG_CONNECTION = "PG_CONNECTION"; // ignore that it is not separate file

@Module({
  providers: [
    {
      provide: PG_CONNECTION,
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        const connection = postgres(config.get("DATABASE_URL"));
        return drizzle(connection, { schema });
      },
    },
  ],
  exports: [PG_CONNECTION],
})
export class DrizzleModule {}

and then:

import { Inject, Injectable } from '@nestjs/common';
import { PG_CONNECTION } from '../drizzle/drizzle.module';
import { dbType } from 'drizzle-orm/postgres-js'; // ignore, it doesn't matter yet
import * as schema from '../drizzle/schema';

@Injectable()
export class UsersService {
  constructor(@Inject(PG_CONNECTION) private drizzle: dbType<typeof schema>) {} // what I'm talking about

  async findAll() {
    return await this.drizzle.query.users.findMany();
  }
}

what I’m talking about, we should inject (provider?) every time, import the constant and type from the db client, instead of this:

import { Inject, Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service'

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

  async findAll() {
    return await this.prisma.users.findMany();
  }
}

I tried to find a solution but it seems this topic is really not popular.. I was expecting such a big Nest.js and Drizzle ORM community to have a good solution to use Drizzle with Nest

2

Answers


  1. You could create your own wrapper class around the PG_CONNECTION injection token. Something like

    @Injectable()
    export class DrizzleService {
      constructor(@Inject(PG_CONNECTION) readonly db: dbType<typeof schema>) {}
    }
    

    And now instead of exporting the PG_CONNECTION token from your DrizzleModule you export the DrizzleService. This would allow you to use the similar private readonly drizzle: DrizzleService as you’re able to with prisma and then access this.drizzle.db for your typed database access inside of other providers.

    Login or Signup to reply.
  2. I am learning NestJS and was trying to set up Drizzle. I’ve seen several tutorials, and most of them teach how to configure it as you did. However, following the principle of Prisma, I did something like this, which worked for me. I can’t tell you if this implementation could cause any issues, but here it is:

    I created a client class following the Drizzle documentation:

    @Injectable()
        export class DrizzleClient {
          private _drizzleClient: PostgresJsDatabase<typeof schema>;
        
          constructor(private configService: ConfigService) {
            const queryClient = postgres(this.configService.get('CONNECTION_STRING'));
            this._drizzleClient = drizzle(queryClient, { schema: schema });
          }
        
          public get db(): PostgresJsDatabase<typeof schema> {
            return this._drizzleClient;
          }
        }
    

    Then I made a Service extending this client:

    @Injectable()
    export class DrizzleService extends DrizzleClient {}
    

    Then add the service to the AppModule:

    @Module({
      imports: [ConfigModule.forRoot({ isGlobal: true })],
      controllers: [],
      providers: [DrizzleService],
    })
    export class AppModule {}
    

    And I can use it like this:

    @Injectable()
    export class AppService {
      constructor(private drizzle: DrizzleService) {}
    
      async get(): Promise<SelectUsers[]> {
        return await this.drizzle.db.select().from(users);
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search