P
Prisma•4w ago
Boku no Tema

NestJS + prisma optimize

I'm trying to add prisma optimize to project with nest.js framework. As I can see in logs - it initializes, but there is no data recorded
import {
FactoryProvider,
Global,
Logger,
Module,
OnModuleDestroy,
} from '@nestjs/common';
import { PrismaClient, Prisma } from '@prisma/client';
import { ConfigService } from '@nestjs/config';
import { EventEmitter2 } from '@nestjs/event-emitter';

import { getPrismaWithEventEmitterExtension } from './extensions';
import { withOptimize } from '@prisma/extension-optimize';

const logger = new Logger('PrismaClient');

const prismaClientProvider: FactoryProvider<PrismaClient> = {
provide: PrismaClient,
inject: [ConfigService, EventEmitter2],
useFactory: (configService: ConfigService, eventEmitter: EventEmitter2) => {
const logLevels: Prisma.LogLevel[] = configService.get<boolean>(
'isPrismaDebugEnabled',
)
? ['info', 'query', 'warn', 'error']
: ['error'];

const prismaClient = new PrismaClient({
log: logLevels.map((level) => ({
emit: 'event',
level,
})),
datasources: {
db: {
url: configService.get('DB_URL'),
},
},
});

prismaClient.$on('info', logger.debug.bind(logger));
prismaClient.$on('query', logger.debug.bind(logger));
prismaClient.$on('warn', logger.warn.bind(logger));
prismaClient.$on('error', logger.error.bind(logger));

return prismaClient
.$extends(getPrismaWithEventEmitterExtension(eventEmitter))
.$extends(
withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }),
) as unknown as PrismaClient;
},
};

@Global()
@Module({
providers: [prismaClientProvider],
exports: [PrismaClient],
})
export class DatabaseModule implements OnModuleDestroy {
constructor(private readonly prisma: PrismaClient) {}

async onModuleDestroy() {
await this.prisma.$disconnect();
logger.log('PrismaClient disconnected on module destroy');
}
}
import {
FactoryProvider,
Global,
Logger,
Module,
OnModuleDestroy,
} from '@nestjs/common';
import { PrismaClient, Prisma } from '@prisma/client';
import { ConfigService } from '@nestjs/config';
import { EventEmitter2 } from '@nestjs/event-emitter';

import { getPrismaWithEventEmitterExtension } from './extensions';
import { withOptimize } from '@prisma/extension-optimize';

const logger = new Logger('PrismaClient');

const prismaClientProvider: FactoryProvider<PrismaClient> = {
provide: PrismaClient,
inject: [ConfigService, EventEmitter2],
useFactory: (configService: ConfigService, eventEmitter: EventEmitter2) => {
const logLevels: Prisma.LogLevel[] = configService.get<boolean>(
'isPrismaDebugEnabled',
)
? ['info', 'query', 'warn', 'error']
: ['error'];

const prismaClient = new PrismaClient({
log: logLevels.map((level) => ({
emit: 'event',
level,
})),
datasources: {
db: {
url: configService.get('DB_URL'),
},
},
});

prismaClient.$on('info', logger.debug.bind(logger));
prismaClient.$on('query', logger.debug.bind(logger));
prismaClient.$on('warn', logger.warn.bind(logger));
prismaClient.$on('error', logger.error.bind(logger));

return prismaClient
.$extends(getPrismaWithEventEmitterExtension(eventEmitter))
.$extends(
withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }),
) as unknown as PrismaClient;
},
};

@Global()
@Module({
providers: [prismaClientProvider],
exports: [PrismaClient],
})
export class DatabaseModule implements OnModuleDestroy {
constructor(private readonly prisma: PrismaClient) {}

async onModuleDestroy() {
await this.prisma.$disconnect();
logger.log('PrismaClient disconnected on module destroy');
}
}
4 Replies
Prisma AI Help
Prisma AI Help•4w ago
You opted for speed from this bot. Let's conjure up an answer right now! I see you're having issues with Prisma Optimize in your NestJS application. Based on the knowledge sources, there are a few potential issues with your implementation: Issue with Extension Order The main problem might be related to the order of your extensions. According to the Prisma Optimize documentation:
// This is the correct order when using multiple extensions
const prisma = new PrismaClient().$extends(withOptimize()).$extends(withAccelerate())
// This is the correct order when using multiple extensions
const prisma = new PrismaClient().$extends(withOptimize()).$extends(withAccelerate())
In your code, you're applying the event emitter extension first, then the Optimize extension. Try reversing this order:
return prisma
.$extends(
withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }),
)
.$extends(getPrismaWithEventEmitterExtension(eventEmitter)) as unknown as PrismaClient;
return prisma
.$extends(
withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }),
)
.$extends(getPrismaWithEventEmitterExtension(eventEmitter)) as unknown as PrismaClient;
Potential Conflict with PrismaClient Extension There's a known issue with extending PrismaClient in NestJS applications. According to the GitHub issues, when you use .$extends() on a PrismaClient instance, it can cause conflicts with other NestJS modules, particularly those that use reflection metadata like EventEmitter. From this GitHub issue, there's a specific problem with transactions when using the Optimize extension in NestJS. The issue occurs when you try to assign an extended client to a class that extends PrismaClient. Suggested Solution Based on one of the more successful approaches from the GitHub issue about extending PrismaClient, try this pattern:
const prismaClientProvider: FactoryProvider<PrismaClient> = {
provide: PrismaClient,
inject: [ConfigService, EventEmitter2],
useFactory: (configService: ConfigService, eventEmitter: EventEmitter2) => {
const logLevels: Prisma.LogLevel[] = configService.get<boolean>(
'isPrismaDebugEnabled',
)
? ['info', 'query', 'warn', 'error']
: ['error'];

// Create a b
ase client
const baseClient = new PrismaClient({
log: logLevels.map((level) => ({
emit: 'event',
level,
})),
datasources: {
db: {
url: configService.get('DB_URL'),
},
},
});

// Set up event handlers on the base client
baseClient.$on('info', logger.debug.bind(logger));
baseClient.$on('query', logger.debug.bind(logger));
baseClient.$on('warn', logger.warn.bind(logger));
baseClient.$on('error', logger.error.bind(logger));

// Create the extended client
const extendedClient = baseClient
.$extends(withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }))
.$extends(getPrismaWithEventEmitterExtension(eventEmitter));

return extendedClient;
},
};
const prismaClientProvider: FactoryProvider<PrismaClient> = {
provide: PrismaClient,
inject: [ConfigService, EventEmitter2],
useFactory: (configService: ConfigService, eventEmitter: EventEmitter2) => {
const logLevels: Prisma.LogLevel[] = configService.get<boolean>(
'isPrismaDebugEnabled',
)
? ['info', 'query', 'warn', 'error']
: ['error'];

// Create a b
ase client
const baseClient = new PrismaClient({
log: logLevels.map((level) => ({
emit: 'event',
level,
})),
datasources: {
db: {
url: configService.get('DB_URL'),
},
},
});

// Set up event handlers on the base client
baseClient.$on('info', logger.debug.bind(logger));
baseClient.$on('query', logger.debug.bind(logger));
baseClient.$on('warn', logger.warn.bind(logger));
baseClient.$on('error', logger.error.bind(logger));

// Create the extended client
const extendedClient = baseClient
.$extends(withOptimize({ apiKey: process.env.PRISMA_OPTIMIZE_API_KEY }))
.$extends(getPrismaWithEventEmitterExtension(eventEmitter));

return extendedClient;
},
};
Also, make sure you've enabled the tracing preview feature in your Prisma schema if you're using Prisma ORM between versions 4.2.0 and 6.1.0:
generator client {
provider = "prisma-client-js"
previewFeatures = ["tracing"]
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["tracing"]
}
If you're still having issues, you might need to check if there's a conflict between the EventEmitter module and Prisma Optimize. Some users have reported needing to patch the EventEmitter module to handle Prisma Client extensions properly, as mentioned in this GitHub issue. Let me know if these suggestions help or if you need further assistance! 🤔 Alright, thanks for letting us know that there's still some help needed. A team member will reply to you shortly. In the meantime, please let us know any additional info, questions, or which parts of the answer may need clarification.
Boku no Tema
Boku no TemaOP•4w ago
"@prisma/client": "^6.3.1",
"@prisma/extension-optimize": "^1.1.8",
"@prisma/client": "^6.3.1",
"@prisma/extension-optimize": "^1.1.8",
Nurul
Nurul•4w ago
Do you get any errors while trying to use Optimize? If I understand correctly, you start a recording in Optimize, invoke some queries in your Nest application but those queries are not recorded?
Boku no Tema
Boku no TemaOP•4w ago
No, there is no any error. Only this message in console. Yes, you got it correct
No description

Did you find this page helpful?