Comments (7)
Hi @MorenoMdz, this is already possible with Prisma Client Extension. I have added it to the Extensions Example.
nestjs-prisma/examples/extensions/src/prisma.extension.ts
Lines 1 to 38 in 407de1b
Let me know if this helps you. I will add a section to the docs too.
from nestjs-prisma.
This is great, I will give it a shot today, thanks again @marcjulian !
from nestjs-prisma.
Checkout the new section for Read Replica in the docs.
from nestjs-prisma.
@marcjulian I might have to redo our setup, currently we have a PrismaConfigService.ts
which we inject in all our services:
import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { PrismaOptionsFactory, PrismaServiceOptions } from 'nestjs-prisma'
import { getEnvironment, isProduction, isDevelopment } from './utils'
@Injectable()
export class PrismaConfigService implements PrismaOptionsFactory {
constructor(private configService: ConfigService) {}
createPrismaOptions(): PrismaServiceOptions | Promise<PrismaServiceOptions> {
const environment = getEnvironment()
const isProd = environment === 'production'
const urlSuffix = isProduction()
? '_PROD'
: // When running locally, and we want to use the DEV database
isDevelopment() || process.env.FIREBASE_ENV === 'DEV'
? '_DEV'
: ''
const DB_URL = this.configService.get(`DATABASE_URL${urlSuffix}`)
return {
prismaOptions: {
log: isProd ? undefined : ['info', 'query'],
datasources: {
db: {
url: DB_URL,
},
},
},
explicitConnect: this.configService.get('DB_EXPLICIT_CONNECT') || false,
}
}
}
And then the app.module is initialized like this:
...
imports: [
PrismaModule.forRootAsync({
isGlobal: true,
useClass: PrismaConfigService,
}),
...
]
Should I just redo the setup and or try to plug in the extensions on top of this at the App.module imports section?
from nestjs-prisma.
You will need to use CustomPrismaModule
instead of PrismaModule
. The reason is, that PrismaModule
provides PrismaService
which is extended by the default PrismaClient
and it cannot be used together with $extends
.
Use CustomPrismaModule
and inject your ConfigService
which you can access in the factory method and pass any options directly to your PrismaClient
instance.
import { Module } from '@nestjs/common';
import { CustomPrismaModule } from 'nestjs-prisma';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { extendedPrismaClient } from './prisma.extension';
@Module({
imports: [
CustomPrismaModule.forRootAsync({
name: 'PrismaService',
useFactory: (config: ConfigService) => {
const options = {};
return extendedPrismaClient(options);
},
inject: [ConfigService],
// import ConfigModule when `isGlobal` not true
// imports: [ConfigModule],
}),
ConfigModule.forRoot({
isGlobal: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { Prisma, PrismaClient } from '@prisma/client';
// used for Read Replicas example
import { readReplicas } from '@prisma/extension-read-replicas';
// add more parameters like read replicas urls
export const extendedPrismaClient = (options?: Prisma.PrismaClientOptions, ...) =>
new PrismaClient<
Prisma.PrismaClientOptions,
'query' | 'info' | 'warn' | 'error'
>(options)
// .$extends(
// readReplicas({
// url: 'postgres://localhost:5432/prisma',
// }),
// );
// add ReturnType because extendedPrismaClient is now a function
export type extendedPrismaClient = ReturnType<typeof extendedPrismaClient>;
Let me know if that helps. I might need to update the docs to make it more clear to use CustomPrismaModule
and CustomPrismaService
when using $extends
.
from nestjs-prisma.
Thanks again for the response. I am still not sure I get how to configure this with our current setup.
-
Do I keep the current PrismaConfigService file that is creating the Prisma client options as well as defining the DB_URL? If so, ideally we want to define the read replica URL here too instead of at the extension file. What I am not sure is when using an extension, where do we configure the base Prisma settings? Would I have the setup in all three places, the PrismaConfigService, App module, and the new Prisma extension file?
-
Do I have to change all places that are currently loading the
PrismaService
to access the db to useCustomPrismaService<extendedPrismaClient>
instead? Seems very verbose, shouldn'tPrismaService
already access the instance of the custom service everywhere?
Also, the way we have been injecting the Prisma service in our services is like private prisma: PrismaService
I would assume that @Inject('PrismaService')
is the same?
from nestjs-prisma.
To clear it up a bit more.
PrismaModule and PrismaService
PrismaService
has only access to the defaultPrismaClient
, it does not work with$extends
at all.
BecausePrismaService
extendsPrismaClient
, thePrismaClient
is created and it cannot be$extends
further.
import { Inject, Injectable, Optional } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { PrismaServiceOptions } from './interfaces';
import { PRISMA_SERVICE_OPTIONS } from './prisma.constants';
@Injectable()
export class PrismaService extends PrismaClient {
constructor(
@Optional()
@Inject(PRISMA_SERVICE_OPTIONS)
private readonly prismaServiceOptions: PrismaServiceOptions = {},
) {
super(prismaServiceOptions.prismaOptions);
...
}
...
}
PrismaModule
allows passing options to thePrismaClient
viaforRoot
orforRootAsync
.forRootAsync
allows to pass a config class e.g.PrismaConfigService
- Use
PrismaService
to access the database
CustomPrismaModule and CustomPrismaService
- Use
CustomPrismaModule
andCustomPrismaService
when you need to use$extends(...)
import { PrismaClientLike } from './custom-prisma-options';
import { Inject, Injectable } from '@nestjs/common';
import { CUSTOM_PRISMA_CLIENT } from './custom-prisma.constants';
@Injectable()
export class CustomPrismaService<Client extends PrismaClientLike> {
constructor(
@Inject(CUSTOM_PRISMA_CLIENT)
public client: Client,
) {}
}
CustomPrismaService
gives you access to your extended PrismaClient
.
- You have access to the
PrismaClient
instance directly and you can pass your options to itnew PrismaClient(YOUR_OPTIONS)
- Use
CustomPrismaService
to access the database - You can provide a config class to
CustomPrismaModule
import { ExtendedPrismaConfigService } from './extended-prisma-config.service';
// app.module.ts
CustomPrismaModule.forRootAsync({
name: 'PrismaService',
useClass: ExtendedPrismaConfigService,
})
// extended-prisma-config.service.ts
import { Injectable } from '@nestjs/common';
import { CustomPrismaClientFactory } from 'nestjs-prisma';
import { extendedPrismaClient } from './prisma.extension';
@Injectable()
export class ExtendedPrismaConfigService
implements CustomPrismaClientFactory<extendedPrismaClient>
{
constructor() {
// inject config service here
}
createPrismaClient(): extendedPrismaClient {
return extendedPrismaClient;
}
}
❌ CustomPrismaModule
does not provide the extended PrismaClient
for PrismaService
, you must use CustomPrismaService
I will move this into a discussion as this might help others too.
from nestjs-prisma.
Related Issues (20)
- Property '$on' is missing in type HOT 8
- When will nestjs 10 be supported? HOT 2
- use extension instead of middleware HOT 1
- Error: "beforeExit" hook is not applicable to the library engine since Prisma 5.0.0, it is only relevant and implemented for the binary engine. Please add your event listener to the `process` object directly instead. HOT 8
- Options fail with latest nest cli HOT 2
- Prisma 5.0.0 Upgrade HOT 1
- PrismaService generator generates deprecated code HOT 3
- feat: add option to use generic http messages in Prisma exception filter HOT 1
- applicationRef undefined in nest e2e tests HOT 1
- error TS2307: Cannot find module '@nestjs-prisma' or its corresponding type declarations. HOT 1
- Extensions: `create` and `update` broken HOT 1
- Custom Prisma Client is not working HOT 13
- Bump prisma version HOT 2
- Link on `middleware` broken HOT 1
- CustomPrismaService unit testing HOT 2
- Feature Request: add support for using PrismaClientExceptionFilter as a controller/gateway/method level filter
- Possibility to use extensions and this.prisma. HOT 2
- Excessive Database Connections When Using Prisma with PgBouncer in PM2 Clustered Environment HOT 3
- Support for Multiple Database Clients in NestJS Prisma Module HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nestjs-prisma.