REST 检查资源是否存在,服务器端如何处理?

Jad*_*orr 9 rest

如何处理服务器端的资源检查?例如,我的 api 看起来像:

/books/{id}
Run Code Online (Sandbox Code Playgroud)

谷歌搜索后我发现,我应该使用 HEAD 方法来检查资源是否存在。 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

我知道,我可以使用 GET 端点并使用 HEAD 方法来获取有关资源的信息,并且在这种情况下服务器不会返回正文。

但是我应该在服务器端做什么?我有两个选择。

  1. 一个端点标记为 GET。我这个端点我可以使用 GET 方法来获取数据和 HEAD 来检查资源是否可用。

  2. 两个端点。一个标记为 GET,第二个标记为 HEAD。

为什么我要考虑第二种解决方案?让我们假设,GET 请求从数据库中获取一些数据并以某种方式处理它们,这需要一些时间,例如。10 毫秒

但我真正需要的只是检查数据库中是否存在数据。所以我可以运行查询

select count(*) from BOOK where id = :id
Run Code Online (Sandbox Code Playgroud)

如果查询结果等于 1,则立即返回状态 200。在这种情况下,我不需要处理数据,因此响应时间更快。

但是...... REST 中的资源是一个通过 HTTP 传输的对象,所以也许我应该处理数据而不是在我使用 HEAD 方法时返回它们?

预先感谢您的回答!

Łuk*_*bek 6

端点应该是相同的,服务器端脚本应该根据方法决定要做什么。如果方法是 HEAD,则只返回合适的 HTTP 代码:

  • 204 如果内容存在但服务器不返回它
  • 404 如果不存在
  • 4xx5xx其他错误

如果method为GET,则处理请求并返回带有HTTP代码的内容:

  • 200 如果内容存在并且服务器返回它
  • 404 如果不存在
  • 4xx5xx其他错误

重要的是 URL 应该相同,只是方法应该不同。如果 URL 不同,那么我们在 REST 上下文中讨论不同的资源。


cas*_*lin 6

您可以简单地将HEAD处理程序委托给现有GET处理程序并仅返回状态代码和标头(忽略响应负载)。

这就是 Spring MVC 和 JAX-RS 等一些框架所做的。


请参阅 Spring MVC文档中的以下引用:

@GetMapping— 而且@RequestMapping(method=HttpMethod.GET), 隐式映射到并支持 HTTP HEADHEAD处理HTTP请求就像处理 HTTPGET一样,但不是写入正文,而是计算字节数并设置 " Content-Length标头。

[...]

@RequestMapping方法可以显式映射到 HTTPHEAD和 HTTP OPTIONS,但这在常见情况下不是必需的。

并查看 JAX-RS文档中的以下引用:

HEADOPTIONS请求获得额外的自动化支持。收到HEAD请求后,实现必须:

  1. 调用一个用请求方法指示符注解的方法,HEAD或者,如果不存在,
  2. 调用带有请求方法指示符注释的方法GET并丢弃任何返回的实体。

请注意,在实体创建重要的情况下,选项 2 可能会导致性能降低。


注意:不要再使用旧的RFC 2616作为参考。它被一组新的 RFC 废弃:7230-7235。有关 HTTP 协议的语义,请参阅RFC 7231