如何return 202 Accepted然后继续处理Nest.js中的请求

How to return 202 Accepted and then continue processing the request in Nest.js

我需要一个控制器操作:

  1. 授权调用
  2. 验证它
  3. Returns 202 已接受状态
  4. 继续处理请求
  5. 调用外部 API 并返回先前已接受且现在已处理的请求的结果。

前两点很简单,我用AuthGuard然后class-validator。但我不知道如何 return HTTP 响应然后继续处理。

由于请求由一组(可能很长-运行)任务组成,我想到了使用拦截器,该拦截器使用 RxJS 来观察任务的状态并在任务完成时调用外部 PI。但是,我没有使用 RxJS 或拦截器(不是这种方式)的经验,所以我真的不知道如何离开拦截器的进程 运行 但立即将控制权传递给控制器​​的操作。

此外,也许还有另一种更好的方法?没有拦截器,只是把所有的流逻辑放在控制器里?其他选择?

如果您的服务 return 承诺您可以执行以下操作,则 API 将 return 202 继续处理。当然,'then' 的任何处理都是在 'beginProcessing' 完成后发生的。

@Post()
@HttpCode(HttpStatus.ACCEPTED)
beginProcessing(@Req() request, @Body() data: Data): void {
    this.service.process(data).then(...);
}

我希望您有一项服务可以执行外部 API 调用(异步)和 returns PromiseObservable:

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

  makeApiCall(data): Observable<AxiosResponse<any>> {
    return this.httpService.post('https://external.api', data);
  }
}

我还假设有一个进行异步调用的 PreprocesserService(例如从数据库获取用户信息)。

控制器

@Post()
@UseGuards(AuthGuard('jwt'))
@HttpCode(HttpStatus.ACCEPTED)
async post(@Body(new ValidationPipe()) myDataDto: MyDataDto) {
  // The preprocessing might throw an exception, so we need to wait for the result
  const preprocessedData = await this.preprocessService.preprocess(myDataDto);
                           ^^^^^
  // We do not need the result to respond to the request, so no await
  this.externalApiService.makeApiCall(preprocessedData);
  return 'Your data is being processed.';
}

当您进行异步调用时,只有在您使用 async/await 或 returning a Promise / Observable.

在此示例中,我们希望在发送响应之前等待 this.preprocessService.preprocess(myDataDto) 的结果。我们通过使用 await 来做到这一点(该方法必须声明为 async)。

我们想向外部发出请求 API 但我们的响应不需要结果。因为我们在这里没有使用 await 它会进行 http 调用并立即执行下一行(return 语句)而不等待结果。