NestJS HttpService 调用多个端点

Edw*_*win 3 typescript axios nestjs

我通常是一个 PHP 开发人员,几乎没有使用 javascript/typescript 的经验。刚开始使用 NestJS - 我想要一个端点,该端点返回requisitions通过其端点从另一个系统检索到的列表。

粗略的想法:

  1. 使用凭据调用登录端点
  2. requisition使用来自登录端点的令牌调用列表端点
  3. 返回结果

我已经尝试过像这样调用端点:

const url ='https://the-requisition-endpoint';
const config: AxiosRequestConfig = {
      headers: {
        'Accept': 'application/json',
        'Authorization': 'a_hard_coded_token_string' // hard coded for experimentation
      }
    };
let result = this.httpService.get(url, config);
result.subscribe(response =>
  console.log(response.data);
});

Run Code Online (Sandbox Code Playgroud)

现在我需要更改它,以便令牌不被硬编码 - 使用来自登录端点的令牌。

我不确定如何强制仅在登录端点返回令牌后才调用请求端点。我搜索并发现 aPromise.all()调用的函数zip可能会有所帮助,但我不知道如何使其工作。

Jay*_*iel 5

我相信您正在寻找的 RxJS 运算符是switchMap。本质上,你最终会想要做这样的事情:

@Injcetable()
export class MyService {

  constructor(private readonly httpService: HttpService) {}

  getRequisitions(): Observable<any> {
    // change to POST signature is login is a post. post(url, body, config)
    return this.httpService.get(url, config).pipe(
      // optional, but it makes working with responses easier
      map(resp => resp.data),
      // make new http call and switch to this observable
      switchMap(loginData => this.httpService.get(url, configWithLoginData)),
      / again, optional, but useful for keeping data easily readable
      map(resp => resp.data),
      // optional, but useful for checking what is returned
      tap(data => console.log(data))
  }
}
Run Code Online (Sandbox Code Playgroud)

好吧,这里发生了很多事情,所以让我们也分解一下。在 NestJS 中,内置的 HttpService 返回 Observables 而不是 Promises。这允许你做一些非常强大的事情,比如在出现某些故障时重试 HTTP 调用。这可以通过 Promise 来完成,但它确实需要更多的代码。无论如何,.pipe在第一个 HTTP 调用之后,我们就可以开始操作 RxJS 流并处理通过的数据。

map是一个 RxJS 操作符,与Array.prototype.map操作符类似,因为它对可观察对象发出的每个值应用一个转换函数(在这种情况下它只有一个值,但理论上它可以用于许多值)。

switchMap是 RxJS 中的扁平运算符之一,与mergeMap和 一起concatMap。我会让你从与上面相同的链接中阅读那些内容,但本质上,switchMap取消了当前的 observable 以支持新创建的 observable,这有助于我们避免内存泄漏。我们返回一个新的 Observable(一个新的 HttpService 调用),并开始处理该数据。

tap是一个间谍操作员,因为它不对它可以访问的数据做任何事情,它只允许您查看它(通过 console.log)。这几乎是它的用途,但是如果需要并且响应无关紧要,您可以进行其他标注。

最后,没有,subscribe因为 NestJS 将在后台订阅并发送最后发出的值作为响应。无需自己担心。

哦,所有的响应map(resp => resp.data)是 AxiosResponse 有几个字段,但在大多数情况下,您可能只关心data属性中保存的返回数据。

每个 RxJS 运算符都接受一个函数,我们在这里的每种情况下都只使用一行函数。如果需要,您可以使用完整的匿名函数语法。IE

map((resp) => {
  return resp.data;
})
Run Code Online (Sandbox Code Playgroud)

一行语法更短,但如果必须执行不适合一行的附加逻辑,则需要重新编写。