DEV Community

Discussion on: Advanced NestJS: How to build completely dynamic NestJS modules

Collapse
 
kostyatretyak profile image
Костя Третяк • Edited

Wow, that's a lot of code. And what is the benefit of this? In my opinion, it is better to transfer the metadata for the database connection synchronously:

import { ConnectionConfig, TypeCast } from 'mysql';

const {
  MYSQL_HOST,
  MYSQL_PORT,
  MYSQL_USER,
  MYSQL_PASSWORD,
  MYSQL_DATABASE,
  MYSQL_CHARSET
} = process.env;

export class MySqlConfigService implements ConnectionConfig {
  charset = MYSQL_CHARSET;
  host = MYSQL_HOST;
  port = MYSQL_PORT ? +MYSQL_PORT : 3306;
  user = MYSQL_USER;
  password = MYSQL_PASSWORD;
  database = MYSQL_DATABASE;
  typeCast: TypeCast = (field, next) => {
    if (field.type == 'JSON') {
      return JSON.parse(`${field.string()}` || '');
    }
    return next();
  };
}
Enter fullscreen mode Exit fullscreen mode

Pass this config to DI:

providers: [
  MySqlConfigService
  //...
]
Enter fullscreen mode Exit fullscreen mode

And when it's time to execute requests to the database, then make an asynchronous connection to the database. This approach allows, in addition to simplifying the code, to reconnect to a database when needed:

import { createPool, Pool, PoolConnection, MysqlError, OkPacket } from 'mysql';
import { Injectable } from '@nestjs/common';

import { MySqlConfigService } from './mysql-config.service';

@Injectable()
export class MysqlService {
  private pools: { [database: string]: Pool } = {};

  constructor(
    private config: MySqlConfigService,
    // ...
  ) {}

  getConnection(dbName?: string): Promise<PoolConnection> {
    return new Promise((resolve, reject) => {
      const config = { ...this.config };
      const database = (dbName || config.database) as string;
      config.database = database;
      if (!this.pools[database]) {
        this.pools[database] = createPool(config);
      }

      this.pools[database].getConnection((err, connection) => {
        if (err) {
          this.handleErr(this.serverMsg.mysqlConnect, err, reject);
        } else {
          resolve(connection);
        }
      });
    });
  }
  // ...
}
Enter fullscreen mode Exit fullscreen mode