nest HTTP 模块

时间:2023-01-13 浏览:203 分类:NestJS

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

RxJS响应式编程可以参考链接

使用

第一步:安装依赖

$ npm i --save @nestjs/axios axios

第二步:模块引入

@Module({
  imports: [HttpModule],
  providers: [UserService],
})
export class UserModule {}

第三步:注入服务

// user.service.ts

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

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

配置

Axios 可以配置各种选项来自定义 HttpService 的行为。要配置底层 Axios 实例,请在导入时将可选的选项对象传递给 HttpModule 的 register() 方法。这个选项对象将直接传递给底层的 Axios 构造函数。

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [UserService],
})
export class UserModule {}

异步加载 -

如需要异步而不是静态地传递模块选项时,使用 registerAsync() 方法。与大多数动态模块一样,Nest 提供了几种处理异步配置的技术。

一种技术是使用工厂函数:

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});

可以注入外部依赖:

HttpModule.registerAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
  }),
});

或者还可以使用类而不是工厂来配置 HttpModule

HttpModule.registerAsync({
  useClass: HttpConfigService,
});

注意,HttpConfigService 必须实现 HttpModuleOptionsFactory 接口,如下所示。 HttpModule 将在所提供类的实例化对象上调用 createHttpOptions() 方法。

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}

因为HttpModule 返回的是Observable 对象,所以结合RxJS 可以使用RxJS的API

      this.httpService.get<Cat[]>('http://localhost:3000/cats').pipe(
        catchError((error: AxiosError) => {
          this.logger.error(error.response.data);
          throw 'An error happened!';
        }),
      ),

直接使用原生Axios

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

  findAll(): Promise<AxiosResponse<Cat[]>> {
    return this.httpService.axiosRef.get('http://localhost:3000/cats');
                           // ^ AxiosInstance interface
  }
}