RESTAPI、HTTP状态代码和结果代码

RESTAPI、HTTP状态代码和结果代码,rest,api,http,Rest,Api,Http,这与其说是一个技术问题,不如说是一个“哲学”问题 假设您有一条消息,以及允许(或不允许)访问此消息的用户。 假设我们有一个api来实现这一点,下面是端点: /消息/(id\u消息)/允许/(用户id) /消息/(id\u消息)/禁止/(用户id) 现在让我们假设,除了HTTP状态代码之外,我们还有一个字段result\u code,它返回一个数字,该数字准确地反映了代码中发生的情况 假设我们第一次允许一个用户。这个方法的HTTP状态码应该是200,假设result\u code是20 如果我

这与其说是一个技术问题,不如说是一个“哲学”问题

假设您有一条消息,以及允许(或不允许)访问此消息的用户。 假设我们有一个api来实现这一点,下面是端点:

  • /消息/(id\u消息)/允许/(用户id)
  • /消息/(id\u消息)/禁止/(用户id)
现在让我们假设,除了HTTP状态代码之外,我们还有一个字段
result\u code
,它返回一个数字,该数字准确地反映了代码中发生的情况

假设我们第一次允许一个用户。这个方法的HTTP状态码应该是200,假设
result\u code
是20


如果我们再次直接调用此方法,那么HTTP状态代码、结果代码应该是什么?为什么?

当然这不是一个哲学问题,而是一个关于标准说明了什么以及遵守这些标准的真正优势的问题

HTTP指定要执行的GET、PUT和DELETE操作。这意味着重复调用需要具有相同的效果

使这些操作幂等是很重要的,因为消息可能会丢失,而调用者需要有一种方法来处理。REST中没有事务,因此重复幂等操作可确保在调用方不确定第一次调用是否有效时执行该操作。在您的示例中,允许用户两次应该与允许用户一次相同

定义幂等性如下:

如果使用请求方法的多个相同请求对服务器的预期效果与单个此类请求的效果相同,则该请求方法被视为“幂等”。[…]区分幂等方法是因为如果在客户端能够读取服务器响应之前发生通信故障,请求可以自动重复。[…]它知道重复请求将具有相同的预期效果,即使原始请求成功,尽管响应可能不同

服务器端(主)效果需要相同。RFC允许响应不同。尤其是在删除的情况下,通常情况下,成功删除通常会导致
204无内容
,重复删除会导致
404未找到

虽然回答不必完全相同,但如果它们是相同的,这还是有帮助的。这简化了客户端逻辑。客户机可以假设重复调用具有相同的效果,因此它应该能够使用相同的代码处理它。前面提到的DELETE返回204或404的异常非常常见(因为这简化了服务器逻辑)。其他例外情况很少见,只有在有充分理由的情况下才应作出例外

严格来说,POST和PATCH操作不要求是幂等的。不过,尤其是使用补丁时,它可能会有所帮助

后置运算不是幂等的。或者相反:如果你有一个不能使幂等的运算,它应该是后运算

说到标准和REST:您提到的REST资源应该如下所示:

GET /messages/{messageId}/allowed-users
POST /messages/{messageId}/allowed-users

{
    "userId": "1324"
}
返回允许的用户列表。请注意,表示列表的资源以复数形式命名(因此
消息
不是
消息

将新用户添加到允许的用户列表中

DELETE /messages/{messageId}/allowed-users/{userId}
撤销先前给予的权利

所有这些运算都应该是幂等的

使用POST操作如下所示:

GET /messages/{messageId}/allowed-users
POST /messages/{messageId}/allowed-users

{
    "userId": "1324"
}
POST向类似于资源的列表中添加新元素。你不需要做这个幂等,但我认为在这种情况下是可取的。< /P>
可以将其他结果代码作为标题或结果对象返回。正如你提到的。但是如果你愿意的话:有一些人已经详细考虑了这个问题,并提出了。

HTTP 200如果响应正常,20因为它是相同的方法?@Veve好的,第一次应该是20,但是第二次可能是21,因为我们已经验证了它,前面的用户可能想知道delete是幂等的?如果我删除一个资源,我希望对同一资源的后续删除返回404-,因为它不再存在。@Gandalf根据delete应该是幂等的,是的。但是您是对的,允许后续404也是一种常见的折衷方法。您应该使用RFC7231(第4.2.2节)中描述的幂等元定义。“这并不完全意味着你的建议。”无理由的声音谢谢。我改进了我的答案。@R2C2谢谢,所以基本上一个请求可以是幂等的,同时返回不同的HTTP状态码(甚至是正文)?当然,只要服务器端的请求具有相同的效果。尽管如此,拥有一个
结果\u code
/问题详细信息仍然可以更好地了解服务器端发生了什么,对吗?