{"id":15586657,"url":"https://github.com/sabinadams/nestjs-prisma-module","last_synced_at":"2025-07-26T17:36:27.231Z","repository":{"id":59697711,"uuid":"529708709","full_name":"sabinadams/nestjs-prisma-module","owner":"sabinadams","description":"A NestJS module that allows you use Prisma, set up multiple Prisma services, and use multi-tenancy in each Prisma service.","archived":false,"fork":false,"pushed_at":"2024-12-18T17:00:41.000Z","size":310,"stargazers_count":50,"open_issues_count":12,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-12-18T18:18:49.110Z","etag":null,"topics":["databases","module","multitenancy","nestjs","prisma","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sabinadams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-27T22:19:04.000Z","updated_at":"2024-10-08T08:54:00.000Z","dependencies_parsed_at":"2023-09-29T18:37:31.016Z","dependency_job_id":"0829d939-d5d3-4db8-80f7-3bf0745f020f","html_url":"https://github.com/sabinadams/nestjs-prisma-module","commit_stats":{"total_commits":132,"total_committers":3,"mean_commits":44.0,"dds":0.553030303030303,"last_synced_commit":"0639bfd51a8cd9a54f26b868cab814cc48a023e2"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabinadams%2Fnestjs-prisma-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabinadams%2Fnestjs-prisma-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabinadams%2Fnestjs-prisma-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabinadams%2Fnestjs-prisma-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sabinadams","download_url":"https://codeload.github.com/sabinadams/nestjs-prisma-module/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230415317,"owners_count":18222158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["databases","module","multitenancy","nestjs","prisma","typescript"],"created_at":"2024-10-02T21:40:55.017Z","updated_at":"2024-12-19T10:08:59.401Z","avatar_url":"https://github.com/sabinadams.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## NestJS Prisma Module\n\n![Header](https://res.cloudinary.com/sabinthedev/image/upload/v1661752534/NestJSPrismaModule_sa8xvh.png)\n\n\u003cdiv align=center\u003e\n\n[![Tests](https://github.com/sabinadams/nestjs-prisma-module/actions/workflows/tests.yml/badge.svg)](https://github.com/sabinadams/nestjs-prisma-module/actions/workflows/tests.yml)\n[![Linting](https://github.com/sabinadams/nestjs-prisma-module/actions/workflows/lint.yml/badge.svg)](https://github.com/sabinadams/nestjs-prisma-module/actions/workflows/lint.yml)\n\n\u003c/div\u003e\n\n## Installation\n\nTo use this package, first install it:\n\n```sh\nnpm i @sabinthedev/nestjs-prisma\n```\n\nOr\n\n```sh\npnpm add @sabinthedev/nestjs-prisma\n```\n\n## Basic Usage\n\nIn order to use this package, you will need one or more [Prisma Clients](https://www.prisma.io/) set up in your project.\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\nimport { PrismaClient } from '@prisma/client';\nimport { PrismaModule } from '@sabinthedev/nestjs-prisma';\n\n@Module({\n  imports: [\n    PrismaModule.register({\n      client: PrismaClient,\n      name: 'PRISMA',\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nThere are also various options you may pass to the `register` function to customize how Prisma Client is instantiated and how to handle connections and requests.\n\n## Multitenancy\n\nThis plugin allows you to handle multi-tenant applications by abstracting a service layer above Prisma Client to cache Prisma Client instances in-memory and select the appropriate tenant connection on each request.\n\nBelow is an example of how to configure `PrismaModule` to handle multiple tenants:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\nimport { PrismaClient } from '@prisma/client';\nimport { PrismaModule } from '@sabinthedev/nestjs-prisma';\n\n@Module({\n  imports: [\n    PrismaModule.register({\n      client: PrismaClient,\n      name: 'PRISMA',\n      multitenancy: true,\n      datasource: 'postgresql://johndoe:randompassword@localhost:5432/mydb',\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nWhen configuring multi-tenancy, the `datasource` key is required as it is used as the base URL on which the tenant database is added.\n\nTo access a specific tenant database, add a header to your HTTP request named `x-tenant-id` whose value is the name of the tenant DB you wish to access.\n`PrismaModule` will generate a new instance of Prisma Client using the base URL you provided along with the specification for the tenant database.\n\n### Example Request\n\nIn the scenario below, your server is at `localhost:3000` and has an endpoint `/users`. The client accessing the resource requesting data from a tenant database named `tenant-name`.\n\n```bash\ncurl -XGET -H 'x-tenant-id: tenant-name' 'localhost:3000/users'\n```\n\n### Supported Database Providers\n\n\u003e **Note**: SQLite _(or any database servers that do not support multiple databases)_ is not supported.\n\nThe list of supported database providers for this feature are as follows:\n\n- PostgreSQL\n- MySQL\n- SQL Server\n- MongoDB\n\n_More to be added soon..._\n\n## API\n\n### `register(options)`\n\nThe register function registers `PrismaModule` and allows you to pass in options that change the behavior of the module and the generated Prisma Client instances.\nThis function takes in a single parameter, `options`. This is an object with the following available keys:\n\n| Parameter    | Type                                                      |            | Description                                                                                                                                                                                                |\n| ------------ | --------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| name         | string                                                    | Required   | The dependency injection token to use with `@Inject`. See [the docs](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens) for more info.                                 |\n| global       | Optional                                                  | false      | When true, the module is marked as a `@Global()` module.                                                                                                                                                   |\n| logging      | boolean                                                   | Optional   | Enables logging within the module using NestJS's Logger module.                                                                                                                                            |\n| client       | `PrismaClient` class _or_ [`ClientConfig`](#clientconfig) | Required   | The `PrismaClient` class to be instantiated, or an object containing a reference to a `PrismaClient` class and a callback function that allows you to modify the instantiated class on a per-tenant basis. |\n| multitenancy | boolean                                                   | Optional\\* | A flag that turns on the multi-tenancy capabilities of this module.                                                                                                                                        |\n| datasource   | string                                                    | Optional\\* | A datasource URL that is used to manually override Prisma Client's datasource. This is used as the base URL when dynamically selecting tenant databases.                                                   |\n| requestType  | `HTTP` or `GRPC`                                          | Optional\\* | Defines what kind of request to handle, allowing the plugin to correctly grab a tenant ID. (Defaults to `HTTP`). _More to be added._                                                                       |\n\n\u003e **Note**: If `multitenancy` OR `datasources` are present, both are required. The built-in type-safety will make this apparent.\n\n#### ClientConfig\n\nAn object of the `ClientConfig` type is able to be provided instead of a `PrismaClient` class to the `client` option key. This object should contain:\n\n| Parameter   | Type                            |          | Description                                                                                                                    |\n| ----------- | ------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |\n| client      | PrismaClient                    | Required | A `PrismaClient` class                                                                                                         |\n| initializer | [Initializer](#initializer)     | Required | A function that is called when a `PrismaClient` is instantiated.                                                               |\n| options     | `PrismaClient` constructor args | Optional | See the [Prisma Client API reference](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#prismaclient) |\n\n#### `initializer(client: PrismaClient, tenant: string) =\u003e PrismaClient`\n\nThis function gives you access to the generated client and the associated tenant name (if any) so you can customize the client instance with functions such as `$on`, `$use` and more. The available client methods can be found [here](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#client-methods).\n\nWithin this function, you can provide any function you would like to run when a Prisma Client is instantiated.\n\nThe return of this function must be the Prisma Client.\n\n## Advanced Usage\n\nIn the scenario below, the module is configured to:\n\n- Use multi-tenancy\n- Log info on the connection handling\n- Initialize PrismaClient with logging enabled at the `info` level _(see Prisma's docs on [logging](https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/logging))_\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\nimport { PrismaClient } from '@prisma/client';\nimport { PrismaModule } from '@sabinthedev/nestjs-prisma';\n\n@Module({\n  imports: [\n    PrismaModule.register({\n      client: {\n        class: PrismaMock,\n        options: {\n          log: [\n            {\n              emit: 'event',\n              level: 'info',\n            },\n          ],\n        },\n      },\n      logging: true,\n      multitenancy: true,\n      datasource: 'file:./dev.db',\n      name: 'PRISMA',\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\n## Multiple Prisma Modules\n\nYou may register this module multiple times within your application to provide access to different databases.\n\nConfigure a new Prisma schema. _Make sure to specify a custom `output` in the `client` generator if your first client used the default location. This ensures the newly generated client does not override the one at `node_modules/@prisma/client`_.\n\nYou can then register a second client in a way similar to the following:\n\n```ts\nimport { Module } from '@nestjs/common';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\nimport { PrismaModule } from '@sabinthedev/nestjs-prisma';\n\n// Import your clients\nimport { PrismaClient as AuthClient } from '../prisma-clients/auth';\nimport { PrismaClient as UsersClient } from '../prisma-clients/users';\n\n@Module({\n  imports: [\n    // Register the module once for each client\n    PrismaModule.register({\n      client: AuthClient,\n      name: 'AUTH',\n    }),\n    PrismaModule.register({\n      client: UsersClient,\n      name: 'USERS',\n    }),\n  ],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nIn the above scenario, you may be working in a microservice architecture who's Authentication service uses a separate database than the Users service.\nThe configuration above registers both clients as separate providers.\n\nYou, of course, have all of the granular control and options as before when registering multiple modules.\n\n## Guides\n\n### Using Custom Logger and Grafana Loki\n\nThis module makes use of the built-in [NestJS Logger](https://docs.nestjs.com/techniques/logger) module.\nLet's say your app uses a [Pino](https://github.com/pinojs/pino) logger and aggregrates your logs into [Grafana Loki](https://grafana.com/oss/loki/), how would you do that?\n\nFirst, you'll want the [`pino-nestjs`](https://github.com/iamolegga/nestjs-pino) and [`pino-loki`](https://github.com/Julien-R44/pino-loki) packages:\n\n```sh\npnpm add pino-nestjs pino-http pino-loki\n```\n\nThen configure a custom logger module:\n\n```ts\n// modules/logger.module.ts\nimport { Module } from '@nestjs/common';\nimport { LoggerModule as PinoLoggerModule } from 'nestjs-pino';\n\n@Module({\n  imports: [\n    PinoLoggerModule.forRoot({\n      pinoHttp: {\n        transport: {\n          target: 'pino-loki',\n          options: {\n            batching: true,\n            interval: 5,\n            host: process.env.LOKI_URL,\n            basicAuth: {\n              username: process.env.LOKI_USERNAME,\n              password: process.env.LOKI_PASSWORD,\n            },\n          },\n        },\n      },\n    }),\n  ],\n})\nexport class LoggerModule {}\n```\n\nAbove we set up a Pino logger configured to use Pino's `pinoHttp` transport option to send logs to Loki.\n\nNext we need to import this into our app module:\n\n```ts\n// src/app.module.ts\nimport { Module } from '@nestjs/common';\nimport { LoggerModule } from '@/modules/logger.module';\n\n@Module({\n  imports: [LoggerModule],\n})\nexport class AppModule {}\n```\n\nThis provides the module to the application at the root level.\n\nLastly, in `main.ts` you will want to set this logger as the default logger so you can continue to use `@nestjs/common`'s `Logger` module:\n\n```ts\n// src/main.ts\nimport { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { Logger } from 'nestjs-pino';\n\nasync function bootstrap() {\n  const app = await NestFactory.create(AppModule, { rawBody: true });\n  app.useLogger(app.get(Logger));\n  await app.listen(3000);\n}\nbootstrap();\n```\n\nWith that configured, the `@nestjs/common` library will now use the Pino logger with the Loki transport under the hood, meaning all of the logs from the this library will go to Loki _(if logging is turned on)_.\n\n## Author\n\nI'm Sabin Adams! Find me on [𝕏](https://x.com/sabinthedev)\n\n## Contributors\n\nNone yet! But contributions are welcome!\n\n## License\n\nLicensed under [MIT](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsabinadams%2Fnestjs-prisma-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsabinadams%2Fnestjs-prisma-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsabinadams%2Fnestjs-prisma-module/lists"}