覆盖NestJs模块配置

问题描述 投票:0回答:1

我正在尝试构建 API,它将在后台调用不同的外部服务。 API 看起来像

GET /order/{serviceName}/{itemId}
。服务数量是任意的。

所以我创建了订单模块,如下所示:

@Module({
  imports: [HttpModule.register({
    baseURL: 'https://someUrl/api/abcd',
  })],
  controllers: [OrdersController],
  providers: [OrdersService, AService]
})
export class OrdersModule { }

我还创建了一个

AModule
,它将从
HttpModule
接收
OrdersModule
。看起来像这样:

@Module({
  imports: [
    HttpModule,
  ],
  providers: [AService],
  exports: [AService],
})
export class AModule { }

问题是我在

HttpModule
(baseUrl) 处定义了
OrdersModule
的设置,看起来我无法在
AModule
级别执行此操作。这意味着我无法将某些外部服务 (ServiceB) 的新模块添加到该结构中,因为我需要为该服务设置不同的
baseUrl

我怎样才能克服这个问题?我应该采取什么不同的做法? 预先感谢!

javascript typescript dependency-injection nestjs
1个回答
0
投票

如果我猜对了,你需要有X个

HttpService
实例,每个实例都有相同的
baseURL
,但可以通过不同的模块使用?比如:

  1. foo API ->
    fooHttpService
    -> 可用于模块
    OrdersModule
    FooModule
  2. bar API ->
    barHttpService
    -> 可用于模块
    OrdersModule
    BarModule

选项1

如果是,那么我会为您正在通信的每个外部 API 创建单独的模块:

@Global()
@Module({
   imports: [HttpModule.register({
    baseURL: 'https://foo/api/abcd',
  })],
    providers: [
       {
           provide: 'FOO_HTTP_SERVICE',
           useClass: HttpService
       }
    ],
    exports: ['FOO_HTTP_SERVICE']
},)
export class FooModule {}

然后:

@Module({
  imports: [
    FooModule,
  ],
  providers: ['FOO_HTTP_SERVICE', AService],
  exports: [AService],
})
export class AModule { }

@Injectable()
export class AService {
   constructor(@Inject('FOO_HTTP_SERVICE') private readonly fooHttpService: HttpService) {}
}

选项2

选项 2 与选项 1 类似。只是用于与外部服务通信的模块不定义注入令牌,但它们导出具体类:

@Injectable()
export class FooHttpService {
   constructor(private readonly httpService: HttpService) {}

   // specialized method wrapped over HttpService
   getSomethingFromFoo(args?...: any[]) { return this.httpService.get(...); }

   // or proxied call
   get get() {
       return this.httpService.bind(this.httpService);
   }
}

FooModule
BarModule
中注册它们,并从与这些 API 连接的其他模块中,在模块提供程序中声明
FooService


为什么?

如果一项服务要跨不同模块使用,则它会获得自己的模块。模块封装了特定域的逻辑,并且与外部 API 的连接绝对是一个独立的自治域。此外,如果由于某种原因,与某些 API 的通信将中断,只需在一个地方关闭端点(已削减的 API 模块)即可。

© www.soinside.com 2019 - 2024. All rights reserved.