Nest: Failed to register multiples HttpModule

Created on 18 Sep 2018  路  11Comments  路  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior


When the HttpModule is imported into multiple modules, the first record of it overlaps all others, as if it were global.

Expected behavior


Each record gets stuck in its context.

Minimal reproduction of the problem with instructions

@Module({
    imports: [
        AModule,
        BModule,
    ],
})
export class AppModule {}

```typescript
@Module({
imports: [
HttpModule.register({
baseUrl: 'http://a.com',
}),
],
providers: [AService],
exports: [AService],
})
export class AModule {}

```typescript
@Module({
    imports: [
        HttpModule.register({
            baseUrl: 'http://b.com',
        }),
    ],
    providers: [BService],
    exports: [BService],
})
export class BModule {}

Make request with HttpService in AService with this.http.get('/whatever'):

  • Final url: a.com/whetever

Make request with HttpService in BService with this.http.get('/whatever'):

  • Final url: a.com/whetever expected b.com/whatever

What is the motivation / use case for changing the behavior?


Creation of multiple services that connects to other apis.
Example:
FirstExternalApiModule -> FirstExternalApiService -> Http request -> First external api
SecondExternalApiModule -> SecondExternalApiService -> Http request -> Second external api

Environment


Nest version: v5.3.7


For Tooling issues:
- Node version: v10.0.0  
- Platform:  Mac 



common done 馃憦 type

Most helpful comment

@kamilmysliwiec It seems like I have the same issue:

@Module({
  imports: [HttpModule.register({
    baseURL: 'http://b.com',
})],
  providers: [MailerService],
  exports: [MailerService]
})
export class MailerModule {}
@Module({
  imports: [HttpModule.register({
    baseURL: 'http://a.com',
})],
  providers: [ParserService],
  exports: [ParserService]
})
export class ParserModule {}

When making request in MailerService with HttpService it uses http://a.com (should http://b.com). Using nest v6.1.1, node v10.15.3, linux mint 19 cinnamon.

All 11 comments

Thanks for reporting. Fixed, I'll deploy soon.

Fixed in the latest patch version:)

@kamilmysliwiec It seems like I have the same issue:

@Module({
  imports: [HttpModule.register({
    baseURL: 'http://b.com',
})],
  providers: [MailerService],
  exports: [MailerService]
})
export class MailerModule {}
@Module({
  imports: [HttpModule.register({
    baseURL: 'http://a.com',
})],
  providers: [ParserService],
  exports: [ParserService]
})
export class ParserModule {}

When making request in MailerService with HttpService it uses http://a.com (should http://b.com). Using nest v6.1.1, node v10.15.3, linux mint 19 cinnamon.

I've encountered the same behavior:
[System Information]
OS Version : macOS Mojave
NodeJS Version : v10.15.3
YARN Version : 1.16.0
[Nest Information]
platform-socket.io version : 6.2.4
platform-express version : 6.2.4
websockets version : 6.2.4
typeorm version : 6.1.1
common version : 6.2.4
core version : 6.2.4
jwt version : 6.1.0

@Module({
imports: [
HttpModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) =>
configService.getApiClient1Configuration(),
inject: [ConfigService],
}),
],
providers: [SomeService1],
})
export class SomeModule1 {}

@Module({
imports: [
HttpModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) =>
configService.getApiClient2Configuration(),
inject: [ConfigService],
}),
],
providers: [SomeService2],
})
export class SomeModule2 {}

Hi @kamilmysliwiec is there any update on this? I'm also facing the same issue

@Module({
  providers: [MeService],
  controllers: [MeController],
  imports: [
    HttpModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        baseURL: configService.get('app').profileBaseUrl,
      }),
      inject: [ConfigService],
    }),
    HttpModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        baseURL: configService.get('app').authBaseUrl,
      }),
      inject: [ConfigService],
    }),
  ],
})
export class MeModule {}

Could you please create a separate issue + provide a minimal reproduction repo? @jpgarcia

I've just created a new repo. Before creating the new issue let me know if what we can achieve is possible.

https://github.com/jpgarcia/nestjs-multiple-http-modules

Files involved are:
https://github.com/jpgarcia/nestjs-multiple-http-modules/blob/master/src/app.module.ts
https://github.com/jpgarcia/nestjs-multiple-http-modules/blob/master/src/app.service.ts

Notice the baseURL are the same in the console output:

HttpService Instance #1 HttpService {
  instance:
   { [Function: wrap]
     request: [Function: wrap],
     delete: [Function: wrap],
     get: [Function: wrap],
     head: [Function: wrap],
     options: [Function: wrap],
     post: [Function: wrap],
     put: [Function: wrap],
     patch: [Function: wrap],
     defaults:
      { adapter: [Function: httpAdapter],
        transformRequest: [Array],
        transformResponse: [Array],
        timeout: 0,
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        validateStatus: [Function: validateStatus],
        headers: [Object],
        baseURL: 'https://docs.nestjs.com' },
     interceptors:
      { request: [InterceptorManager],
        response: [InterceptorManager] } } }
HttpService Instance #2 HttpService {
  instance:
   { [Function: wrap]
     request: [Function: wrap],
     delete: [Function: wrap],
     get: [Function: wrap],
     head: [Function: wrap],
     options: [Function: wrap],
     post: [Function: wrap],
     put: [Function: wrap],
     patch: [Function: wrap],
     defaults:
      { adapter: [Function: httpAdapter],
        transformRequest: [Array],
        transformResponse: [Array],
        timeout: 0,
        xsrfCookieName: 'XSRF-TOKEN',
        xsrfHeaderName: 'X-XSRF-TOKEN',
        maxContentLength: -1,
        validateStatus: [Function: validateStatus],
        headers: [Object],
        baseURL: 'https://docs.nestjs.com' },
     interceptors:
      { request: [InterceptorManager],
        response: [InterceptorManager] } } }

Well, not really. If you import HttpModule twice within the same scope (AppModule), how Nest would distinguish which instance you want to use?

@kamilmysliwiec you are right, my bad!

Do you have any suggestion to inject two instances of an HttpService(with different baseURL) into a service?

@jpgarcia In this case, I've created two separated modules and inject both HTTP services from those modules

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thohoh picture thohoh  路  3Comments

cojack picture cojack  路  3Comments

tronginc picture tronginc  路  3Comments

janckerchen picture janckerchen  路  3Comments

mishelashala picture mishelashala  路  3Comments