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:
Basic knowledge of NestJs
Basic understanding of Typescript, PostgreSQL, MongoDB, and Prisma
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.