postgresqlnestjsdrizzle-orm

Nest.js with Drizzle ORM


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


Solution

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