如何处理服务器端的资源检查? 例如,我的api看起来像:
/books/{id}
谷歌搜索后我发现,如果资源存在,我应该使用HEAD方法来检查。 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
我知道,我可以使用GET端点并使用HEAD方法获取有关资源的信息,在这种情况下服务器不返回正文。
但是我应该在服务器端做什么? 我有两个选择。
一个标记为GET的端点。我这个端点我可以使用GET方法获取数据,HEAD来检查资源是否可用。
两个端点。一个标记为GET,第二个标记为HEAD。
为什么我在考虑第二种解决方案? 让我们假设,GET请求从数据库中获取一些数据并以某种方式处理它们,这需要一些时间,例如。 10毫秒
但我真正需要的只是检查数据库中是否存在数据。所以我可以运行像
这样的查询select count(*) from BOOK where id = :id
如果查询结果等于1,则立即返回状态200.在这种情况下,我不需要处理数据,因此我的响应时间更快。
但是...... REST中的资源是一个通过HTTP传输的对象,所以也许我应该处理数据但是当我使用HEAD方法时不返回它们?
提前感谢您的回答!
答案 0 :(得分:1)
您可以简单地将HEAD
处理程序委派给现有的GET
处理程序,并仅返回状态代码和标头(忽略响应有效负载)。
这就是一些框架,如Spring MVC和JAX-RS。
请参阅Spring MVC documentation中的以下引用:
@GetMapping
- 以及@RequestMapping(method=HttpMethod.GET)
隐式映射到并支持HTTPHEAD
。 HTTPHEAD
请求被处理,就像它是HTTPGET
一样,但不是写入正文,而是计算字节数,并且“Content-Length
标题集。[...]
@RequestMapping
方法可以显式映射到HTTPHEAD
和HTTPOPTIONS
,但在常见情况下这不是必需的。
请参阅JAX-RS documentation中的以下引用:
HEAD
和OPTIONS
请求会获得额外的自动支持。收到HEAD
请求后,实现必须:
- 调用使用
HEAD
的请求方法指示符注释的方法,如果不存在,则调用- 调用使用
醇>GET
的请求方法指示符注释的方法,并丢弃任何返回的实体。请注意,在实体创建很重要的情况下,选项2可能会导致性能下降。
注意:不要再使用旧的RFC 2616作为参考。它被一组新的RFC废弃:7230-7235。有关HTTP协议的语义,请参阅RFC 7231。
答案 1 :(得分:0)
端点应该相同,服务器端脚本应根据方法决定做什么。如果method是HEAD,那么只需返回合适的HTTP代码:
204
如果内容存在但服务器没有返回404
如果不存在4xx
或5xx
如果方法是GET,则处理请求并使用HTTP代码返回内容:
200
如果内容存在且服务器返回404
如果不存在4xx
或5xx
重要的是URL应该是相同的,只是方法应该是不同的。如果URL不同,那么我们将讨论REST上下文中的不同资源。
答案 2 :(得分:0)
您对HTTP方法的引用已过时;你应该引用RFC 7231, section 4.3.2
HEAD方法与GET相同,只是服务器不能在响应中发送消息体(即响应终止于标题部分的末尾)。
此方法可用于获取有关所选表示的元数据,而无需传输表示数据,并且通常用于测试超文本链接的有效性,可访问性和最近的修改。
你问:
REST中的资源是一个通过HTTP传输的对象,所以也许我应该处理数据但是当我使用HEAD方法时不返回它们?
这是正确的 - GET
和HEAD
之间的主要区别在于服务器是否作为响应的一部分返回消息正文。
但我真正需要的只是检查数据库中是否存在数据。
我的建议是使用 new 资源。 "资源"是关于使您的数据库看起来像一个网站。在REST中,许多 URI映射到使用相同谓词的查询是完全正常的。
Jim Webber这样说:
网络不是您的域名,它是一个文档管理系统。所有HTTP谓词都适用于文档管理域。 URI不会映射到域对象 - 这违反了封装。工作(例如:向域模型发出命令)是管理资源的副作用。换句话说,资源是反腐败层的一部分。您应该希望集成域中的资源比业务域中的业务对象多得多。