Use NestJS modules wisely

Are you sure you know Dependency Injections principle?


Prelude

Building huge applications could be hard. Especially if you follow simple principles incorrectly. But this could be easily avoided by using simple rules.

Lets dive into example and see how we can fix this. Lets say we are building Crypto Tron Api wrapper, that gets information about your crypto asset.

import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { AxiosRequestConfig } from 'axios';
import { Tron } from 'node-config-ts';

/**
 * This service provides http API to tronweb network.
 * It should not depend in any crypto tools or anything else. Just a simple provider.
 * */
@Injectable()
export default class TronWebService {
  private readonly axiosRequestConfig: AxiosRequestConfig;
  private readonly baseUrl = 'https://api.trongrid.io';

  public constructor(
    private readonly logger: LoggerService,
    private readonly httpService: HttpService,
    config: Tron,
  ) {
    this.axiosRequestConfig = {
      baseURL: config.url,
      headers: {
        'TRON-PRO-API-KEY': config.apiKey,
      },
    };
  }

  async getAccountResource(hexAddress: string): Promise<ITronGetAccountResourcesResponse> {
    const params = { ...this.axiosRequestConfig, params: { address: hexAddress } };
    const http = await this.httpService.get('/wallet/getaccountresource', params).toPromise();
    return http?.data;
  }

  async getTronBlock(): Promise<ITronGetBlockResponse> {
    const http = await this.httpService.get('/wallet/getblock', this.axiosRequestConfig).toPromise();
    return http?.data;
  }
}
@Module({
  imports: [HttpModule, LoggerModule, AuthModule, DatabaseModule],
  controllers: [TronController],
  providers: [
    TronService,
    {
      provide: Tron,
      useFactory: (): Tron => CryptoFactory.getTrx(),
    },
    {
      provide: TronWebService,
      inject: [LoggerService, HttpService],
      useFactory: (logger, httpService): TronWebService => new TronWebService(logger, httpService, config.services.tron),
    },
  ],
  exports: [TronWebService],
})
export class TronModule {
  
}