设计API端点以检查资源是否存在的最佳/宁静方式是什么?
例如,有一个用户数据库。当新用户尝试注册时,我想检查电子邮件是否已被动态使用。
我的想法是:POST /user/exists
和有效负载类似于{"email": "foo@bar.com"}
。响应可以是200 OK或409 Conflict。
这是一种正确的方法吗?
谢谢!
答案 0 :(得分:21)
HEAD
对存在检查最有效:
HEAD /users/{username}
请求用户的路径,如果存在则返回200
,如果不存在,则返回404
。
请注意,您可能不希望暴露检查电子邮件地址的端点。它打开了一个安全和隐私漏洞。已经公开显示在网站周围的用户名,例如reddit,可能没问题。
答案 1 :(得分:5)
我认为检查存在的正确方法是使用HEAD
动词来处理GET
请求通常会获得的任何资源。
我最近遇到过一种情况,我想检查服务器上是否存在可能很大的视频文件。我不希望服务器尝试开始将字节流式传输到任何客户端,因此我实现了一个HEAD
响应,它只返回客户端在执行GET
请求时收到的标头视频。
您可以查看W3规范here或阅读this blog post有关HEAD
动词的实际用法。
我认为这很棒,因为您不必考虑如何与正常的RESTful路线形成路线,以检查是否存在任何资源,无论是文件还是典型的资源,如用户或其他东西。
答案 2 :(得分:3)
GET /users?email=foo@bar.com
这是一个基本的搜索查询:找到具有指定电子邮件地址的用户。如果没有用户,则回复空集合,或者回复符合条件的用户。
答案 3 :(得分:1)
我更喜欢:
HEAD /users/email/foo@bar.com
说明:您正在尝试通过所有用户查找正在使用电子邮件foo@bar.com
的用户。我假设电子邮件不是您资源的关键,并且您有一定的灵活性,因为如果您需要另一个端点来检查用户的其他信息的可用性,这种方法可以非常适合。
作为回复,您只返回200
(如果不可用)或404
(如果可用)作为http代码回复。
您也可以使用:
HEAD /emails/foo@bar.com
如果HEAD /users/email/foo@bar.com
与现有的休息资源发生冲突,例如具有不同业务规则的GET /users/email/foo@bar.com
。如Mozilla's documentation所述:
HEAD方法要求响应与GET请求的响应相同,但没有响应正文。*。
因此,GET
和HEAD
使用不同的规则并不好。
如果电子邮件是HEAD /users/foo@bar.com
的“关键字”,那么users
也是不错的选择,因为您(可能)有GET /users/foo@bar.com
。