DEV Community

Raphael Häcker
Raphael Häcker

Posted on

NestJS and TypeORM database configuration

After some initial problems I had with this topic, I decided to spend some time to look into different options. Here is an overview of the results:

Static configuration in the code

This is the most obvious way to configure the database. Just write the parameters (url, username, …) in the code, where you import the TypeORM.

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

There are a lot of problems with this. You can’t easily change this in a deployed application, it clutters your app.module.ts file and if you commit this to a public repository, you make your database access data public. Also if you always hard code configurations like this, you might end up having them all over the place in your code.
So while this is fine for a quick test in your development environment, I wouldn’t recommend using this for much more than that.

Configuring TypeORM using ormconfig.json

TypeORM offers the possibility to pass configuration parameters for one or more databases using an ormconfig.json file.

This file includes all the relevant configuration options. In my case it was not much:

{
    "type": "mongodb",
    "url": "mongodb+srv://<username>:<password>@some.subdomains.of.mongodb.net/<databasename>"
}
Enter fullscreen mode Exit fullscreen mode

When using the ormconfig.json, you should not put any options in the app.module.ts, where you import TypeORM.

Configuring TypeORM this way is a clean solution, you have one file for the database connection(s) and you can configure more than one database in this file. The downside is, that you have to have this additional file. So in some environments, where you may not be able to access all the files of the application, changing that database might be difficult.

Configuring TypeORM with environment variables

As described here it is possible to configure TypeORM using environment variables. TypeORM offers a list of different variables to use in this case. This uses either a .env-file or the actual environment variables.

A limitation of this method is, that it is only possible to configure one database. But if you only need one database in your application, this is a good way to quickly configure TypeORM depending on the environment.

Configuring TypeORM with a configuration service

This combines the asynchronous configuration that is described in the NestJS documentation with the config module from NestJS, that supports in getting values from the environment variables.

Basically you have to create a service, that can be injected into the TypeORM import and that implements the TypeOrmOptionsFactory interface. The values this service provides to TypeORM are retrieved from the NestJS config module.

For my mongodb this looks like this:

import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from "@nestjs/typeorm";

@Injectable()
export class MongoDBConfigService implements TypeOrmOptionsFactory {

    constructor(private configService: ConfigService) {}

    createTypeOrmOptions(): TypeOrmModuleOptions {
        return {
            type: 'mongodb',
            url: this.configService.get<string>('MONGODB_URL'),
            username: this.configService.get<string>('MONGODB_USER'),
            password: this.configService.get<string>('MONGODB_PASSWORD'),
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

You can create such a service per database you need. Using it to configure TypeORM in your app.module.ts would look like this:

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true
    }),
    TypeOrmModule.forRootAsync({
      useClass: MongoDBConfigService,
      inject: [MongoDBConfigService]
    })
  ],
  controllers: [AppController],
  providers: [AppService, MongoDBConfigService],
})

export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

The advantage of this method, is that you can configure multiple databases from the environment of the app and keep your app.module.ts more or less clean. The downside is, it takes a few more steps to set up.

Since I am new to NestJS and TypeORM, I’m writing down what I’m learning. So if I missed a method to do this or anything I wrote is incorrect, please let me know!

Top comments (3)

Collapse
 
thezanke profile image
Alex Howard • Edited

Hey! I just found this answer and while I could get it to work with isGlobal: true, I didn't want that so I fiddled around a bit and figured out..

  1. remove isGlobal: true
  2. remove MongoDBConfigService from AppModule's providers: [], it's not needed.
  3. remove MongoDBConfigService from TypeOrmModule's inject: [], it's not needed (remove inject entirely).
  4. add import: [ConfigModule], inside TypeOrmModule's config object.
Collapse
 
mikheyrojo profile image
Mikhail Stepanov

Thank you Raphael, I was looking for something like this

Collapse
 
elielrodriguez profile image
Eliel J. Rodriguez

Thank you Raphael!!!