【问题标题】:What's the best way to handle a 204 No Content response in NestJS?在 NestJS 中处理 204 No Content 响应的最佳方法是什么?
【发布时间】:2022-03-04 03:33:14
【问题描述】:

我正在用 Nest 编写一个 RESTful API,我最近开始使用它,到目前为止我很喜欢。但是,我正在努力寻找一个干净的模式来处理我的 GET 路由的 204 No Content 响应。有什么建议吗?

如果 GET 控制器方法返回的对象为空,框架中没有内置用于返回 204 的内容,我有点惊讶——如果有,我还没有找到。如果真的没有,我也想知道这是否值得在 GitHub 上提出功能请求。

我尝试了以下方法:

  • 使用@Response() 作为Controller 方法参数公开Express res 属性,然后在响应为空时使用res.sendStatus(204)。但是,这也需要我手动发送 200 个响应,而我仍然希望依靠框架来处理请求-响应周期并尽可能保持我的控制器方法干净。
  • 研究了使用拦截器检查响应对象是否为空,然后将 204 状态代码写入响应中。我真的不想这样做,因为稍后可能会由于异常过滤器而更改状态代码。
  • 使用中间件编写响应代码,但我的中间件在路由到控制器之前执行,之后我需要检查响应是否为空。 res.on('send') 似乎也没有在响应输出时拦截响应。
  • 为我的异常过滤器处理自定义NoContentException。虽然为成功的响应代码抛出异常很奇怪,但我认为这是我同时进行的方式,因为我的异常过滤器是在我编写的代码中执行的最后一件事。

【问题讨论】:

  • 查看我的回答中的更新,现在可以使用拦截器。 :-)

标签: typescript rest api-design nestjs


【解决方案1】:

更新 v6.1.0

从 v6.1.0 开始,可以在拦截器中设置响应代码,请参阅 PR


过时的答案

不幸的是,这似乎还不可能。在docs 它说:

通常,您的状态代码不是静态的,而是取决于各种因素。 在这种情况下,您可以使用特定于库的响应(使用注入 @Res()) 对象(或者,如果发生错误,则抛出异常)。

您也不能只在Interceptor 中设置响应代码而不发送它(而不是sendStatus),因为正如卡米尔在thread 中所说:

全局响应控制器的逻辑是刚刚执行的最后一步 在通过网络发送最终结果之前(就是这个地方 默认状态码的来源)。

因此,如果您(可以理解)不想在每个控制器中使用 @ResExceptionFilter 似乎是最好的选择,尽管感觉并不完全正确。

由于其他人似乎拥有exact same problem,因此功能请求可能是个好主意。 :-)

【讨论】:

【解决方案2】:

看着这个example

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}

这就是你需要做的。它为您返回 204。

【讨论】:

  • HTTP 状态码有一个枚举:HttpStatus。所以你可以这样做:@HttpCode(HttpStatus.NO_CONTENT)
  • 很好,不知道。
【解决方案3】:
  • 最初用于204 No Content响应生成的实践,已在position of introducing nestjs status code annotation feature的官方文档中提及。
  • 关于通过检查响应内容是否为空来生成204响应的思路

    @kim-kern answer 中所述,直接在 Express.js 编程或将拦截器作为中间件插件构建到 nestjs 框架使用中是可能且可行的。

    然而,在 api 设计级别,它不是必需的功能,因为理想情况下,一个 api 应该设计为一个成功响应,这意味着一个端点只有一个成功代码可用。从这个角度来看,状态码注释是可以接受的。

【讨论】:

    【解决方案4】:

    使用 @HttpCode(204) 装饰器对我的情况没有帮助,因为我不希望在查询返回数据数组时抛出 204。即使查询成功,我也希望它在数组为空时抛出 204。

    也就是说,由于我正在构建一个简单的 MVP,所以我选择了 throw HttpStatus.NO_CONTENT;,这暂时就足够了。

    采用更简洁的方式(最佳实践)来实现相同的结果。

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2016-11-24
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2023-03-07
      相关资源
      最近更新 更多