Handling third party dependencies in nest.js

Viewed 2543

What is the best practice on how to handle third-party dependencies (i.e. dependencies that don't come in the form of a nest-module) in nest?

For example, I'm using morgan in my own logging module directly by importing it in the respective file:

import { Injectable, MiddlewareFunction, NestMiddleware } from '@nestjs/common';
import * as morgan from 'morgan';

@Injectable()
export class NestLoggingMiddleware implements NestMiddleware {

    resolve(...args: any[]): MiddlewareFunction {
        /** use morgan here, e.g. wrap it in a custom middleware ... */
    }
}

Now I know nest's architecture is heavily influenced by Angular, and I found this article explaining how to deal with 3rd party dependencies in angular. Does the same idea apply to nest? Should I create a custom provider for morgan and inject that? And do I inject just the morgan import, or an already configured morgan instance?

1 Answers

Yes, injecting 3rd party dependencies as custom providers is the way to go. You can use an async factory function to inject dependencies needed for the setup configuration. This way, you will have an already configured instance.

This is an example of what I did recently:

import { Telegraf } from 'telegraf';

// ...

providers: [
  {
    provide: Telegraf,
    useFactory: async (configService: ConfigService) => {
      return new Telegraf(configService.telegramToken);
    },
    inject: [ConfigService],
  },
]

Depending on your requirements, it might make sense to create a new module for your dependency that reexports your provider. Instead of directly exporting your 3rd party instance, you can also create a facade service, that encapsulates the dependency. This way, it becomes easier to exchange the library at some later point.

Related