Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/src/components/Navigation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ const currentPageMatch = currentPage.endsWith('/')
<li>
<a
href={link.link}
class={`flex border-l pl-3 ${
class={`flex gap-1 border-l pl-3 ${
currentPageMatch === link.link
? 'border-current text-violet-500 dark:text-violet-400'
: 'border-transparent text-gray-700 hover:border-current hover:border-gray-500 dark:text-gray-300 dark:hover:border-gray-400'
}`}
>
{link.title}
<span>{link.title}</span>
{link.badge && (<span class="text-xs py-0.5 px-1.5 rounded-lg bg-pink-600 text-white">{link.badge}</span>)}
</a>
</li>
))}
Expand Down
18 changes: 16 additions & 2 deletions docs/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const GITHUB_EDIT_URL = `https://github.com/notiz-dev/nestjs-prisma/tree/
export type Link = {
title: string;
link: string;
badge?: string;
};

export type Navigation = {
Expand All @@ -36,8 +37,12 @@ export const navigation: Navigation[] = [
{
title: 'Basics',
links: [
{ title: 'Prisma Middleware', link: '/docs/prisma-middleware' },
{ title: 'Prisma Logging', link: '/docs/prisma-logging' },
{
title: 'Prisma Middleware',
link: '/docs/prisma-middleware',
badge: 'Outdated',
},
],
},
{
Expand All @@ -52,13 +57,22 @@ export const navigation: Navigation[] = [
title: 'Prisma Client Extensions',
link: '/docs/prisma-client-extensions',
},
{
title: 'Query Logging Extension',
link: '/docs/query-logging-extension',
badge: 'New',
},
],
},
{
title: 'Built-in Tools',
links: [
{ title: 'Exception Filter', link: '/docs/exception-filter' },
{ title: 'Logging Middleware', link: '/docs/logging-middleware' },
{
title: 'Logging Middleware',
link: '/docs/logging-middleware',
badge: 'Outdated',
},
],
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/logging-middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Logging Middleware
---

> Prisma Middleware (`prisma.$use` method) has been deprecated with Prisma v4.16.0 and removed with Prisma v6.14.0. Prisma Middleware is removed in `nestjs-prisma@v0.26.0`. Use [Prisma Client Extension](/docs/prisma-client-extensions) instead.
> Prisma Middleware (`prisma.$use` method) has been deprecated with Prisma v4.16.0 and removed with Prisma v6.14.0. Prisma Middleware is removed in `nestjs-prisma@v0.26.0`. Use [Query Logging Extension](/docs/query-logging-extension) instead.

## Apply logging middleware

Expand Down
139 changes: 139 additions & 0 deletions docs/src/content/docs/query-logging-extension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
title: Query Logging Extension
---

Create a PrismaClient extension to log all queries performed by the PrismaClient.

## Add query logging extension

Prisma provides an example for [Prisma Client Extension - Query Logging](https://github.com/prisma/prisma-client-extensions/tree/main/query-logging). You need to create a new `PrismaClient` instance with `$extends` where you will define the query logging extension.

```ts
// prisma.extension.ts
import { Logger } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

const logger = new Logger('PrismaClient');

export const extendedPrismaClient = new PrismaClient().$extends({
query: {
$allModels: {
async $allOperations({ operation, model, args, query }) {
const start = performance.now();
const result = await query(args);
const end = performance.now();
const time = Math.ceil((end - start) * 100) / 100;
// adjust logging behavior to your needs
logger.log(`Prisma Query ${model}.${operation} took ${time}ms`);
return result;
},
},
},
});

export const ExtendedPrismaClient = typeof extendedPrismaClient;
```

Now you need to register and inject the `CustomPrismaService` with your `extendedPrismaClient`. Read more about [Prisma Client Extensions](/docs/prisma-client-extensions).

```ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

import { CustomPrismaModule } from 'nestjs-prisma';
import { extendedPrismaClient } from './prisma.extension';

@Module({
imports: [
// ✅ use `forRootAsync` when using `PrismaClient().$extends({})`
CustomPrismaModule.forRootAsync({
name: 'PrismaService',
useFactory: () => {
return extendedPrismaClient;
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
```

Inject the `CustomPrismaService` with the `ExtendedPrismaClient` type, useful when adding [custom methods](http://localhost:4321/docs/prisma-client-extensions#create-prisma-extension) to your models.

```ts
import { Inject, Injectable } from '@nestjs/common';
import { CustomPrismaService } from 'nestjs-prisma';
import { type ExtendedPrismaClient } from './prisma.extension';

@Injectable()
export class AppService {
constructor(
// ✅ use `ExtendedPrismaClient` type for correct type-safety of your extended PrismaClient
@Inject('PrismaService')
private prismaService: CustomPrismaService<ExtendedPrismaClient>,
) {}

users() {
return this.prismaService.client.user.findMany();
}
}
```

You will see now for the log messages in your terminal

```bash
Prisma Query User.findMany took 10ms
...
```

## Query Logging extension function

Extract the query logging extension as shareable extension by following [Create a shareable extension](https://www.prisma.io/docs/orm/prisma-client/client-extensions/shared-extensions#create-a-shareable-extension).

```ts
// query-logger.extension.ts
import { Logger } from '@nestjs/common';
import { Prisma } from '@prisma/client';

export const queryLoggingExtension = (logger: Logger) =>
Prisma.defineExtension({
name: 'prisma-extension-query-logger',
query: {
$allModels: {
async $allOperations({ operation, model, args, query }) {
const start = performance.now();
const result = await query(args);
const end = performance.now();
const time = Math.ceil((end - start) * 100) / 100;
logger.log(`Prisma Query ${model}.${operation} took ${time}ms`);
return result;
},
},
},
});
```

Now you can import and use `queryLoggingExtension(new Logger(...))` in `$extends(...)`.

```ts
// prisma.extension.ts
import { Logger } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { queryLoggingExtension } from './query-logger.extension';

const logger = new Logger('PrismaClient');

export const extendedPrismaClient = new PrismaClient().$extends(
queryLoggingExtension(logger),
);

export const ExtendedPrismaClient = typeof extendedPrismaClient;
```

Make sure to register and inject the `CustomPrismaService` described above.

## Example

The [Extensions](https://github.com/notiz-dev/nestjs-prisma/blob/main/examples/extensions/src/query-logging.extension.ts) example on GitHub includes the `query-logging.extension.ts`.
Loading