Initialisation of prisma req based nestjs

Respected sir, My passport google strategy requires authservice in and that requires prisma request based service due to this my passport js is not initializing at start of app.... For that ai suggested moduleref of prismaReqBased service anything best service to inject in authservice.... Anything i am doing wrong .. šŸ™ So prismaBaseservice will be injected everywhere in applications.... Prisma baservive is moduleref and request passes to request based tanant servive and then it is working.....
3 Replies
Prisma AI Help
Prisma AI Helpā€¢2w ago
You've gone full bot mode! Let me fetch that AI answer for you ASAP. Based on the information provided in the knowledge sources, I don't have enough specific details to fully address your particular setup with Passport, Google strategy, and request-based Prisma service in NestJS. However, I can provide some general guidance on initializing Prisma in a NestJS application, which may help you resolve your issue: 1. For NestJS applications, it's recommended to create a PrismaService that extends PrismaClient and implements OnModuleInit. This service can be used to manage a single instance of PrismaClient throughout your application. Here's an example of how to set this up:
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
2. You can then create a PrismaModule to provide this service:
import { Global, Module } from "@nestjs/common";
import { PrismaService } from "./prisma.service";

@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
import { Global, Module } from "@nestjs/common";
import { PrismaService } from "./prisma.service";

@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
3. Import this PrismaModule in your AppModule or any other module where you need to use Prisma. 4. In your AuthService or any other service that needs Prisma, you can inject the PrismaService:
@Injectable()
export class AuthService {
constructor(private prisma: PrismaService) {}

// Use this.prisma to access Prisma Client methods
}
@Injectable()
export class AuthService {
constructor(private prisma: PrismaService) {}

// Use this.prisma to access Prisma Client methods
}
This approach should allow you to have a single, properly initialized Prisma instance available throughout your application, including in your Passport strategy. If you're still facing issues with this setup, you might need to provide more details about your specific implementation, particularly how you're setting up your request-based tenant service and how it interacts with Prisma and Passport. For more detailed information on setting up P risma with NestJS, you can refer to the Prisma blog post on building a REST API with NestJS and Prisma. šŸ¤” 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.
hari_narayan
hari_narayanOPā€¢2w ago
import { Inject, Injectable } from '@nestjs/common'; import { ModuleRef, ContextIdFactory, REQUEST } from '@nestjs/core'; import { PrismaClient } from '@prisma/client'; import { PrismaReqService } from './company-prisma.service'; @Injectable() export class PrismaBaseService extends PrismaClient { constructor( private moduleRef: ModuleRef, @Inject(REQUEST) private readonly request: any, ) { super(); const originalContextId = ContextIdFactory.getByRequest(request); return new Proxy(this, { get: (target, prop) => { // Enhanced transaction handling if (prop === '$transaction') { return async (fn: any | any[]) => { const prismaService = await this.moduleRef.resolve( PrismaReqService, originalContextId, ); // Support both single and multiple transaction functions if (Array.isArray(fn)) { return prismaService.$transaction(fn); } return prismaService.$transaction(async (tx) => { // Wrap the transaction function to provide company-specific transaction context return fn(tx); }); }; } // Original method handling if (prop in target && typeof target[prop] === 'function') { return target[prop].bind(target); } return new Proxy( {}, { get: (_, methodProp) => { return async (...args: any[]) => { const prismaService = await this.moduleRef.resolve( PrismaReqService, originalContextId, ); return prismaService[prop]methodProp; }; }, }, ); }, }); } // Optional: Add utility method for complex transactions async runInTransaction<T>(fn: (tx: any) => Promise<T>): Promise<T> { const prismaService = await this.moduleRef.resolve( PrismaReqService, ContextIdFactory.getByRequest(this.request), ); return prismaService.$transaction(fn); } } upper helped me do anyoneKnow why and how to make it more resilient
Nurul
Nurulā€¢2w ago
Hey šŸ‘‹ In your code snippet I added a getPrismaReqService method to encapsulate moduleRef.resolve with error handling. This makes the code more readable and resilient.
import { Injectable, Inject } from '@nestjs/common';
import { ModuleRef, ContextIdFactory, REQUEST } from '@nestjs/core';
import { PrismaClient } from '@prisma/client';
import { PrismaReqService } from './company-prisma.service';
import { Injectable, Inject } from '@nestjs/common';
import { ModuleRef, ContextIdFactory, REQUEST } from '@nestjs/core';
import { PrismaClient } from '@prisma/client';
import { PrismaReqService } from './company-prisma.service';
@Injectable()
export class PrismaBaseService extends PrismaClient {
constructor(
private readonly moduleRef: ModuleRef,
@Inject(REQUEST) private readonly request: any,
) {
super();

const contextId = ContextIdFactory.getByRequest(request);

return new Proxy(this, {
get: (target, prop) => {
if (prop === '$transaction') {
return async (fn: any | any[]) => {
const prismaService = await this.getPrismaReqService(contextId);
if (Array.isArray(fn)) {
return prismaService.$transaction(fn);
}
return prismaService.$transaction(async (tx) => {
try {
return await fn(tx);
} catch (err) {
// Improved error handling
console.error('Transaction failed:', err);
throw err;
}
});
};
}

if (prop in target && typeof target[prop] === 'function') {
return target[prop].bind(target);
}

return new Proxy(
{},
{
get: (_, methodProp) => {
return async (...args: any[]) => {
const prismaService = await this.getPrismaReqService(contextId);
return prismaService[prop][methodProp](...args);
};
},
},
);
},
});
}

private async getPrismaReqService(contextId: any): Promise<PrismaReqService> {
try {
return await this.moduleRef.resolve(PrismaReqService, contextId);
} catch (err) {
console.error('Error resolving PrismaReqService:', err);
throw new Error('Failed to resolve PrismaReqService');
}
}
@Injectable()
export class PrismaBaseService extends PrismaClient {
constructor(
private readonly moduleRef: ModuleRef,
@Inject(REQUEST) private readonly request: any,
) {
super();

const contextId = ContextIdFactory.getByRequest(request);

return new Proxy(this, {
get: (target, prop) => {
if (prop === '$transaction') {
return async (fn: any | any[]) => {
const prismaService = await this.getPrismaReqService(contextId);
if (Array.isArray(fn)) {
return prismaService.$transaction(fn);
}
return prismaService.$transaction(async (tx) => {
try {
return await fn(tx);
} catch (err) {
// Improved error handling
console.error('Transaction failed:', err);
throw err;
}
});
};
}

if (prop in target && typeof target[prop] === 'function') {
return target[prop].bind(target);
}

return new Proxy(
{},
{
get: (_, methodProp) => {
return async (...args: any[]) => {
const prismaService = await this.getPrismaReqService(contextId);
return prismaService[prop][methodProp](...args);
};
},
},
);
},
});
}

private async getPrismaReqService(contextId: any): Promise<PrismaReqService> {
try {
return await this.moduleRef.resolve(PrismaReqService, contextId);
} catch (err) {
console.error('Error resolving PrismaReqService:', err);
throw new Error('Failed to resolve PrismaReqService');
}
}
async runInTransaction<T>(fn: (tx: any) => Promise<T>): Promise<T> {
const prismaService = await this.getPrismaReqService(
ContextIdFactory.getByRequest(this.request),
);
try {
return await prismaService.$transaction(fn);
} catch (err) {
console.error('Error in runInTransaction:', err);
throw err;
}
}
}
async runInTransaction<T>(fn: (tx: any) => Promise<T>): Promise<T> {
const prismaService = await this.getPrismaReqService(
ContextIdFactory.getByRequest(this.request),
);
try {
return await prismaService.$transaction(fn);
} catch (err) {
console.error('Error in runInTransaction:', err);
throw err;
}
}
}
(Code was split into 3 messages due to max characters limit in Discord)

Did you find this page helpful?