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?
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)