Is there an existing issue for this?
Current behavior
I created custom ApiService using the following article:
https://dev.to/micalevisk/nestjs-tip-how-to-inject-multiple-versions-of-the-same-provider-into-one-module-eg-many-axios-instances-5agc
// custom http client is initialized like that:
const CUSTOM_API_SERVICE = Symbol('CUSTOM_API_SERVICE');
@Module({
imports: [
HttpModule.register({
baseURL: 'https://cats.com',
}),
],
providers: [{ provide: CUSTOM_API_SERVICE, useExisting: HttpService }],
exports: [CUSTOM_API_SERVICE],
})
export class CustomApiModule {}
The problem
If CustomApiModule is initialized before TerminusModule, HealthIndicator will unintendedly retrieve the baseURL of CustomApiModule.
This happens due to getHttpService() method in HttpHealthIndicator implementation:
getHttpService() - resolves the HttpService using moduleRef.get(HttpService, { strict: false }); which crawls Nest dependency tree until it finds an instance of HttpService, the problem is that it firstly encounters the CUSTOM_API_SERVICE instance (yes even though the token itself is called CUSTOM_API_SERVICE)
I have fixed the problem in my code by providing to pingCheck a custom httpService via method options, but it does feel like an bug.
Thanks <3
Minimum reproduction code
import { Injectable, Module, OnModuleInit } from '@nestjs/common';
import { HttpModule, HttpService } from '@nestjs/axios';
import {
HealthCheckService,
HttpHealthIndicator,
TerminusModule,
} from '@nestjs/terminus';
const CUSTOM_HTTP_CLIENT_TOKEN = Symbol('A_TOKEN');
@Module({
imports: [
HttpModule.registerAsync({
useFactory: () => ({
baseURL: 'https://cats.com',
}),
}),
],
providers: [{ provide: CUSTOM_HTTP_CLIENT_TOKEN, useExisting: HttpService }],
exports: [CUSTOM_HTTP_CLIENT_TOKEN],
})
class CustomApiModule {}
@Injectable()
class HealthCheckedService implements OnModuleInit {
constructor(
private health: HealthCheckService,
private http: HttpHealthIndicator
) {}
async onModuleInit() {
await this.pingHealthCheck();
}
private async pingHealthCheck() {
await this.health.check([
() => this.http.pingCheck('some-ping', 'https://dogs.com'), // debugging HealthIndicator pingCheck will show that axiosRef.defaults has baseURL of 'https://cats.com'
]);
}
}
@Module({
imports: [TerminusModule],
providers: [HealthCheckedService],
})
class HealthCheckedModule {}
@Module({
imports: [CustomApiModule],
})
class SomeModule {}
@Module({})
@Module({
imports: [SomeModule, HealthCheckedModule],
})
export class AppTest {}
// my solution
@Injectable()
class HealthCheckedService implements OnModuleInit {
constructor(
private health: HealthCheckService,
private http: HttpHealthIndicator,
private httpService: HttpService
) {}
async onModuleInit() {
await this.pingHealthCheck();
}
private async pingHealthCheck() {
await this.health.check([
() =>
this.http.pingCheck('some-ping', 'https://dogs.com', {
httpClient: this.httpService, // fixes the problem
}),
]);
}
}
Steps to reproduce
- run the code above (can import
AppTest into AppModule)
- debug health-indicator/http.health pingCheck method and look for
axiosRef.defaults which will show improper baseUrl
Expected behavior
inject proper HttpService instead of trying to retrieve it using moduleRef.get(nestjs.axios.HttpService)
Package version
8.0.6
NestJS version
9.4.0
Node.js version
16.17.0
In which operating systems have you tested?
Other
No response
Is there an existing issue for this?
Current behavior
I created custom ApiService using the following article:
https://dev.to/micalevisk/nestjs-tip-how-to-inject-multiple-versions-of-the-same-provider-into-one-module-eg-many-axios-instances-5agc
The problem
If
CustomApiModuleis initialized beforeTerminusModule,HealthIndicatorwill unintendedly retrieve thebaseURLofCustomApiModule.This happens due to
getHttpService()method inHttpHealthIndicatorimplementation:getHttpService()- resolves the HttpService usingmoduleRef.get(HttpService, { strict: false });which crawls Nest dependency tree until it finds an instance ofHttpService, the problem is that it firstly encounters theCUSTOM_API_SERVICEinstance (yes even though the token itself is calledCUSTOM_API_SERVICE)I have fixed the problem in my code by providing to
pingChecka customhttpServicevia method options, but it does feel like an bug.Thanks <3
Minimum reproduction code
Steps to reproduce
AppTestinto AppModule)axiosRef.defaultswhich will show improperbaseUrlExpected behavior
inject proper HttpService instead of trying to retrieve it using moduleRef.get(nestjs.axios.HttpService)
Package version
8.0.6
NestJS version
9.4.0
Node.js version
16.17.0
In which operating systems have you tested?
Other
No response