跳到主要内容

HTTP模块

Axios 是一个功能丰富的 HTTP 客户端包,被广泛使用。 Nest 封装了 Axios 并通过内置的 HttpModule 暴露它。 HttpModule 导出了 HttpService 类,该类提供了基于 Axios 的方法来执行 HTTP 请求。 该库还将生成的 HTTP 响应转换为 Observables

备注

您还可以直接使用任何通用的 Node.js HTTP 客户端库,包括 gotundici

安装

首先,我们安装所需的依赖项。

npm i --save @nestjs/axios axios

入门

安装完成后,要使用 HttpService,首先导入 HttpModule

@Module({
imports: [HttpModule],
providers: [CatsService],
})
export class CatsModule {}

接下来,使用常规构造函数注入 HttpService

提示

HttpModuleHttpService@nestjs/axios 包中导入。

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

findAll(): Observable<AxiosResponse<Cat[]>> {
return this.httpService.get('http://localhost:3000/cats');
}
}
提示

AxiosResponse 是从 axios 包中导出的一个接口($ npm i axios)。

HttpService 的所有方法都返回包装在 Observable 对象中的 AxiosResponse

配置

可以使用各种选项配置 Axios 以自定义 HttpService 的行为。 在导入 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,
}),
});

与其他工厂提供程序一样,我们的工厂函数可以是async,并且可以通过 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,
});

直接使用 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 接口
}
}

完整示例

由于 HttpService 方法的返回值是一个 Observable, 我们可以使用 rxjs 中的 firstValueFromlastValueFrom 来以 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 文档以了解 firstValueFromlastValueFrom 之间的区别。