如何return 202 Accepted然后继续处理Nest.js中的请求
How to return 202 Accepted and then continue processing the request in Nest.js
我需要一个控制器操作:
- 授权调用
- 验证它
- Returns 202 已接受状态
- 继续处理请求
- 调用外部 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 Promise
或 Observable
:
@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 语句)而不等待结果。
我需要一个控制器操作:
- 授权调用
- 验证它
- Returns 202 已接受状态
- 继续处理请求
- 调用外部 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 Promise
或 Observable
:
@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 语句)而不等待结果。