跳到主要内容

HTTP模块

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

备注

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

安装​

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

npm i --save @nestjs/axios axios

入门​

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

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

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

提示

HttpModule 和 HttpService 从 @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 中的 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 之间的区别。