How to Connect a NestJs Application to Multiple Databases Using Prisma

How to Connect a NestJs Application to Multiple Databases Using Prisma

In today's fast-paced and ever-evolving world of software development, it's not uncommon to find applications that need to connect to multiple databases. Whether it's for separating different types of data or scaling purposes, connecting an application to multiple databases can be a powerful tool in any developer's toolbox.

NestJs, a popular Node.js framework for building scalable and efficient back-end applications offers a great set of features for connecting to multiple databases. In this article, we will be discussing how to connect a NestJs application to multiple databases using Prisma, a powerful ORM (Object-Relational Mapping) tool that makes it easy to connect to and manage multiple databases.

We will be going over the basics of setting up a NestJs application and connecting it to a Prisma service, as well as some advanced techniques for managing multiple databases and handling data relationships.

Prerequisites

This tutorial assumes the reader has the following:

Initialize Project

Setting up a new NestJs project is quite straightforward with the Nest CLI. With npm installed, you can create a new Nest project by running the following commands in your terminal:

npm i -g @nestjs/cli
nest new project-name

Install and initialize Prisma

To setup Prisma in our project, we need to install the Prisma CLI as a dev dependency in our project. Run the commands below in your terminal to do this.

npm install prisma --save-dev
npm install @prisma/client

This creates a new prisma directory with the following contents:

  • schema.prisma - This specifies your database connection and contains the database schema

  • .env - This is a dotenv file that stores our database credentials and other environment variables in our project.

Connect PostgreSQL DB using Prisma

Our database connection is configured in the datasource block in our schema.prisma file. By default, it’s set to postgres

prisma/schema.prisma

datasource db {
 provider = "postgres"
 url      = env("POSTGRES_DB")
}

generator client {
 provider        = "prisma-client-js"
 output          = "../node_modules/@prisma-postgres/client"
 previewFeatures = ["fullTextSearch"]
}

model User {
   id Int @id @default(autoincrement())
   name String
}

.env

POSTGRES_DB="postgres://pwueiryyfyr:us7se636hdyuuidjdu3isi3ud@ec2-08-098-453-0293.eu-west-1.compute.amazonaws.com:5432/kapl8j2mlshuey?schema=public"

In our schema.prisma file, we created a User model with an id and name. Now we need to run the migrate command.

Your declarative data model described in the Prisma schema is generated into SQL migration files by Prisma Migrate. These migration files are completely editable, allowing you to add new instructions or set any additional capabilities of the underlying database, such as seeding. Now let’s add a script to run the migration in our package.json file

"migrate": "npx prisma migrate dev"

On doing this, run the command npm run migrate to generate a Prisma client inside node_modules/@prisma-postgres/client which will then generate migration files and create appropriate tables in our prisma database.

Connect MongoDB database using Prisma

To connect mongoDB to Prisma, we need a MongoDB instance, which we can get from Mongo Atlas. Inside the src folder of the project, create a new directory called prisma-mongo and then create a schema.prisma file inside this folder.

For the Mongo Prisma Client, we need to change the output directory, which we will also be placing in the node_module directory.

prisma-mongo/schema.prisma

datasource db {
 provider = "mongodb"
 url      = env("MONGO_URI")
}

generator client {
 provider        = "prisma-client-js"
 output          = "../node_modules/@prisma-mongo/client"
 previewFeatures = ["mongodb", "filterJson"]
}

.env

POSTGRES_DB="postgres://pwueiryyfyr:us7se636hdyuuidjdu3isi3ud@ec2-08-098-453-0293.eu-west-1.compute.amazonaws.com:5432/kapl8j2mlshuey?schema=public"

MONGO_URI="mongodb+srv://testdb:PuIYeyETDGWyyyw@prisma-multidatabase.hohskgg.mongodb.net/prisma-test-db"

During development, you will need to update your Prisma schema file (for example, to add new fields), then update the data in your development environment’s database, and eventually push both the updated schema and the new data to the production database using prisma db push command.

Let’s add the following scripts to our package.json

"mongo:dbpush": "npx prisma db push --schema prisma-mongo/schema.prisma"

Install and generate Prisma Client

The Prisma Client is a type-safe database client that is generated from your Prisma model definition. This method enables the Prisma Client to expose CRUD actions that are customized for your models.

To install Prisma Client in your project, run the following command in your terminal:

npm install @prisma/client

Be aware that Prisma will automatically run the prisma generate command for you during installation. To update your produced Prisma Client in the future, you must run this command following each modification to your Prisma models. Since we are working with two databases in our project, we have to run the prisma generate twice for each schema.prisma file we have. To make life easier for us, let us add the following command to the scripts section of our package.json file.

"generate": "npm run prisma generate --schema prisma/schema.prisma && npm run prisma generate --schema prisma-mongo/schema.prisma"

The prisma generate command reads your Prisma schema and updates the generated Prisma Client library inside node_modules/@prisma-postgres/client and node_modules/@prisma-mongo/client for the postgreSQL database and the mongoDB respectively.

Use Prisma Client in your NestJS services

In our NestJS application, we will abstract the Prisma Client API for database queries within a service by creating a new PrismaService that takes care of instantiating PrismaClient and connecting to our database.

To do this, create a new file named prisma-postgres.service.ts in the src directory and add the following code to it.

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma-postgres/client';

@Injectable()
export class PrismaServicePostgres extends PrismaClient implements OnModuleInit {
 async onModuleInit() {
   await this.$connect();
 }

 async enableShutdownHooks(app: INestApplication) {
   this.$on('beforeExit', async () => {
     await app.close();
     await this.$disconnect();
   });
 }
}

Similarly, we will connect MongoDB to our NestJS project. To do this, create a file called prisma-mongo.service.ts and add the following code to it.

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma-mongo/client';

@Injectable()
export class PrismaServiceMongo extends PrismaClient implements OnModuleInit {
 async onModuleInit() {
   await this.$connect();
 }

 async enableShutdownHooks(app: INestApplication) {
   this.$on('beforeExit', async () => {
     await app.close();
   });
 }
}

So far, we’ve successfully connected our NestJs project to two different databases. At the end of everything, our final package.json file should look similar to the following:

"scripts": {
   "prebuild": "rimraf dist",
   "build": "nest build",
   "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
   "start": "nest start",
   "start:dev": "nest start --watch",
   "start:debug": "nest start --debug --watch",
   "start:prod": "node dist/main",
   "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
   "test": "jest",
   "test:watch": "jest --watch",
   "test:cov": "jest --coverage",
   "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
   "test:e2e": "jest --config ./test/jest-e2e.json",
   "migrate:dev": "yarn prisma migrate dev --schema prisma-postgres/schema.prisma",

"mongo:dbpush": "npx prisma db push --schema prisma-mongo/schema.prisma",
"generate": "npm run prisma generate --schema prisma/schema.prisma && npm run prisma generate --schema prisma-mongo/schema.prisma"
 },

Conclusion

Prisma provides a clean and simple API for interacting with your databases, allowing you to focus on building the features of your application rather than worrying about database management. Whether you're working with a single database or multiple databases, Prisma can help you to write efficient and maintainable code.
In conclusion, connecting a NestJs application to multiple databases using Prisma is a relatively straightforward process. By following the steps outlined in this article, you can easily set up and manage multiple database connections within your application.
I’m glad you stuck with me to the end. Thanks for reading this article.