我正在尝试构建 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
。
我怎样才能克服这个问题?我应该采取什么不同的做法? 预先感谢!
如果我猜对了,你需要有X个
HttpService
实例,每个实例都有相同的baseURL
,但可以通过不同的模块使用?比如:
fooHttpService
-> 可用于模块 OrdersModule
、FooModule
等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 模块)即可。