HTTP 模块
HTTP 模块
Axios 是一个功能丰富且广泛使用的 HTTP 客户端包。Nest 封装了 Axios 并通过内置的 HttpModule 暴露它。HttpModule 导出 HttpService 类,该类暴露基于 Axios 的方法来执行 HTTP 请求。该库还将生成的 HTTP 响应转换为 Observables。
安装
要开始使用它,我们首先安装所需的依赖项。
$ npm i --save @nestjs/axios axios
入门
安装过程完成后,要使用 HttpService,首先导入 HttpModule。
@Module({
imports: [HttpModule],
providers: [CatsService],
})
export class CatsModule {}
接下来,使用正常的构造函数注入来注入 HttpService。
提示 HttpModule 和 HttpService 从 @nestjs/axios 包中导入。
@@filename()
@Injectable()
export class CatsService {
constructor(private readonly httpService: HttpService) {}
findAll(): Observable<AxiosResponse<Cat[]>> {
return this.httpService.get('http://localhost:3000/cats');
}
}
@@switch
@Injectable()
@Dependencies(HttpService)
export class CatsService {
constructor(httpService) {
this.httpService = httpService;
}
findAll() {
return this.httpService.get('http://localhost:3000/cats');
}
}
提示 AxiosResponse 是从 axios 包导出的接口($ npm i axios)。
所有 HttpService 方法都返回包装在 Observable 对象中的 AxiosResponse。
配置
Axios 可以使用各种选项进行配置,以自定义 HttpService 的行为。在这里了解更多信息。要配置底层的 Axios 实例,在导入 HttpModule 时将可选的选项对象传递给 register() 方法。此选项对象将直接传递给底层的 Axios 构造函数。
@Module({
imports: [
HttpModule.register({
timeout: 5000,
maxRedirects: 5,
}),
],
providers: [CatsService],
})
export class CatsModule {}
异步配置
当您需要异步而不是静态地传递模块选项时,请使用 registerAsync() 方法。与大多数动态模块一样,Nest 提供了几种处理异步配置的技术。
一种技术是使用工厂函数:
HttpModule.registerAsync({
useFactory: () => ({
timeout: 5000,
maxRedirects: 5,
}),
});
像其他工厂提供者一样,我们的工厂函数可以是异步的,并且可以通过 inject 注入依赖项。
HttpModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
timeout: configService.get('HTTP_TIMEOUT'),
maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
}),
inject: [ConfigService],
});
或者,您可以使用类而不是工厂来配置 HttpModule,如下所示。
HttpModule.registerAsync({
useClass: HttpConfigService,
});
上面的构造在 HttpModule 内部实例化 HttpConfigService,使用它来创建选项对象。请注意,在此示例中,HttpConfigService 必须实现 HttpModuleOptionsFactory 接口,如下所示。HttpModule 将在提供的类的实例化对象上调用 createHttpOptions() 方法。
@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
createHttpOptions(): HttpModuleOptions {
return {
timeout: 5000,
maxRedirects: 5,
};
}
}
如果您想重用现有的选项提供者而不是在 HttpModule 内部创建私有副本,请使用 useExisting 语法。
HttpModule.registerAsync({
imports: [ConfigModule],
useExisting: HttpConfigService,
});
您还可以将所谓的 extraProviders 传递给 registerAsync() 方法。这些提供者将与模块提供者合并。
HttpModule.registerAsync({
imports: [ConfigModule],
useClass: HttpConfigService,
extraProviders: [MyAdditionalProvider],
});
当您想为工厂函数或类构造函数提供额外的依赖项时,这很有用。
直接使用 Axios
如果您认为 HttpModule.register 的选项对您来说不够,或者如果您只想访问由 @nestjs/axios 创建的底层 Axios 实例,您可以通过 HttpService#axiosRef 访问它,如下所示:
@Injectable()
export class CatsService {
constructor(private readonly httpService: HttpService) {}
findAll(): Promise<AxiosResponse<Cat[]>> {
return this.httpService.axiosRef.get('http://localhost:3000/cats');
// ^ AxiosInstance interface
}
}
完整示例
由于 HttpService 方法的返回值是 Observable,我们可以使用 rxjs - firstValueFrom 或 lastValueFrom 以 promise 的形式检索请求的数据。
import { catchError, firstValueFrom } from 'rxjs';
@Injectable()
export class CatsService {
private readonly logger = new Logger(CatsService.name);
constructor(private readonly httpService: HttpService) {}
async findAll(): Promise<Cat[]> {
const { data } = await firstValueFrom(
this.httpService.get<Cat[]>('http://localhost:3000/cats').pipe(
catchError((error: AxiosError) => {
this.logger.error(error.response.data);
throw 'An error happened!';
}),
),
);
return data;
}
}
提示 访问 RxJS 的文档了解 firstValueFrom 和 lastValueFrom 之间的差异。