Search code examples
nestjs

How to modify multiple outbound/external HTTP requests for NestJS


I have a NestJS app that acts as a central point for communicating with several different APIs. Each one will require different token authentication in the headers, so I want to have a custom HttpService for each one depending on which API I need to interact with.

What I've done so far is to make a service that extends the HttpService and will modify the headers for outgoing HTTP requests.

@Injectable()
export class SharepointHttpService extends HttpService implements OnModuleInit {
  constructor(private readonly httpService: HttpService) {
    super();
  }

  public onModuleInit(): void {
    this.httpService.axiosRef.interceptors.request.use((config) => {
      config.headers.Authorization = `My-Token-Here`;
      return config;
    });
}

I made an ApiModule that will contain all my specialized HTTP Services

@Module({
  imports: [HttpModule],
  providers: [
    { provide: SharepointHttpService, useExisting: HttpService },
    { provide: OtherHttpService, useExisting: HttpService },
  ],
  exports: [SharepointHttpService, OtherHttpService],
})
export class ApiModule {}

In a different module where I want to call the API I import them like this

@Module({
  imports: [HttpModule, ApiModule],
  controllers: [ExampleController],
  providers: [ExampleService, SharepointHttpService, OtherHttpService],
})
export class ExampleModule {}

And from there I would hope to just inject them like this and it would handle everything.

@Injectable()
export class ExampleService {
  constructor(private readonly spHttpService: SharepointHttpService) {}

  getThing() {
    return this.spHttpService.get('some-endpoint');
  }
}

But what I get is this error

Error: Nest can't resolve dependencies of the SharepointHttpService (?, HttpService). Please make sure that the argument "AXIOS_INSTANCE_TOKEN" at index [0] is available in the ApiModule context.

Potential solutions:
- Is ApiModule a valid NestJS module?
- If "AXIOS_INSTANCE_TOKEN" is a provider, is it part of the current ApiModule?
- If "AXIOS_INSTANCE_TOKEN" is exported from a separate @Module, is that module imported within ApiModule?
  @Module({
    imports: [ /* the Module containing "AXIOS_INSTANCE_TOKEN" */ ]
  })

What am I doing wrong? Is this the best way to approach doing what I am trying to do here?


Solution

  • you can't extends that HttpService class because youn can't access the internal providers that @nestjs/axios has.

    In your case, the error is because your SharepointHttpService prover has declared a dependency on a provider that only HttpModule has

    Instead, you can enhance the internal axios instance following what I suggested in this article: https://dev.to/micalevisk/nestjs-tip-how-to-inject-multiple-versions-of-the-same-provider-into-one-module-eg-many-axios-instances-5agc

    or you can use a factory provider that will create an instance of SharepointHttpService that inherits from HttpService (using some sort of JS prototype trick)