NestJS同一模块如何配置不同baseURL实现多域名请求
NestJS同模块内为不同服务配置独立Http请求baseURL方案
默认方式注册的HttpModule生成的HttpService是全局单例,所有注入方共享同一份配置,无法同时为两个服务设置不同baseURL,需要通过命名多实例的方式注册两个独立的HttpService实例,分别绑定对应配置即可,具体实现步骤如下:
1. 调整模块注册逻辑
首先定义两个独立的注入标识,分别注册两个HttpService实例,公共请求配置(超时时间、最大重定向次数等)可以直接复用,仅baseURL按业务需求分别配置。
import { Module } from '@nestjs/common'; import { HttpModule } from '@nestjs/axios'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { FirstService, SecondService } from './services'; import { CampaignsController } from './campaigns.controller'; // 定义两个Http实例的注入标识,避免硬编码错误 export const FIRST_HTTP_INSTANCE = 'FIRST_HTTP_INSTANCE'; export const SECOND_HTTP_INSTANCE = 'SECOND_HTTP_INSTANCE'; @Module({ imports: [ ConfigModule, // 注册绑定第一个服务域名的Http实例 HttpModule.registerAsync({ provide: FIRST_HTTP_INSTANCE, inject: [ConfigService], useFactory: (configService: ConfigService) => ({ timeout: 5000, maxRedirects: 5, baseURL: configService.get('SERVICE_URL_LEGACY'), }), }), // 注册绑定第二个服务域名的Http实例 HttpModule.registerAsync({ provide: SECOND_HTTP_INSTANCE, inject: [ConfigService], useFactory: (configService: ConfigService) => ({ timeout: 5000, maxRedirects: 5, baseURL: configService.get('SERVICE_URL_NEW'), }), }), ], providers: [FirstService, SecondService], controllers: [CampaignsController], }) export class CampaignsModule {}
如果你使用的
@nestjs/axios版本低于1.0,不支持注册时自定义provide参数,可以直接在providers数组中通过工厂模式自定义生成两个HttpService实例,不需要重复引入HttpModule:providers: [ FirstService, SecondService, { provide: FIRST_HTTP_INSTANCE, inject: [ConfigService], useFactory: (configService: ConfigService) => new HttpService({ timeout: 5000, maxRedirects: 5, baseURL: configService.get('SERVICE_URL_LEGACY'), }) }, { provide: SECOND_HTTP_INSTANCE, inject: [ConfigService], useFactory: (configService: ConfigService) => new HttpService({ timeout: 5000, maxRedirects: 5, baseURL: configService.get('SERVICE_URL_NEW'), }) } ]
2. 调整业务服务的注入逻辑
两个业务服务不再注入默认的单例HttpService,而是通过@Inject()装饰器注入对应域名绑定的Http实例即可。
FirstService实现示例:
import { Injectable, Inject } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { FIRST_HTTP_INSTANCE } from './campaigns.module'; import { firstValueFrom } from 'rxjs'; @Injectable() export class FirstService { constructor( @Inject(FIRST_HTTP_INSTANCE) private readonly httpService: HttpService ) {} async getReview(params: Record<string, any>) { const res = await firstValueFrom( this.httpService.get('/review', { params }) ); return res.data; } }
SecondService实现示例:
import { Injectable, Inject } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { SECOND_HTTP_INSTANCE } from './campaigns.module'; import { firstValueFrom } from 'rxjs'; @Injectable() export class SecondService { constructor( @Inject(SECOND_HTTP_INSTANCE) private readonly httpService: HttpService ) {} async getReview(params: Record<string, any>) { const res = await firstValueFrom( this.httpService.get('/review', { params }) ); return res.data; } }
调整完成后,控制器层的代码不需要做任何修改,两个服务发起请求时会自动使用各自绑定的baseURL,不会互相干扰。
不推荐的简化方案
如果不想维护多Http实例,也可以在服务内直接写全请求路径、不依赖baseURL配置,但这种方式无法复用HttpModule全局配置的拦截器、异常处理、日志等能力,后期维护成本高,仅适合临时快速验证场景使用。
内容的提问来源于stack exchange,提问作者Samuel Levy
相关产品推荐
相关产品推荐

