这更像是一个“哲学”问题,而不是技术问题。
假设您有一条消息,以及允许(或不允许)访问此消息的用户。 让我们假设我们有一个api来做到这一点,这里将是端点:
现在让我们说,除了HTTP状态代码之外,我们还有一个字段result_code
,它返回一个反映代码中确切内容的数字。
假设我们第一次允许用户使用。此方法的HTTP状态代码应为200,假设result_code
为20。
如果我们再次直接调用此方法,HTTP状态代码应该是什么,result_code
以及为什么?
答案 0 :(得分:4)
当然,这不是一个哲学问题,而是关于标准所说的以及遵守这些标准的真正优势的问题。
HTTP指定GET,PUT和DELETE操作为idempotent。这意味着重复呼叫需要具有相同的效果。
使这些操作具有幂等性非常重要,因为消息可能会丢失,并且调用者需要有办法处理它。 REST中没有事务,因此重复幂等操作可确保在调用者不确定第一个调用是否有效时执行。在您的示例中,允许用户两次应该与允许一次相同。
RFC7231定义幂等,如下所示:
如果使用该方法对服务器的多个相同请求的预期效果与单个此类请求的效果相同,则请求方法被视为“幂等”。 [...] Idempotent方法是有区别的,因为如果在客户端能够读取服务器响应之前发生通信故障,则可以自动重复请求。 [...]它知道重复请求将具有相同的预期效果,即使原始请求成功,尽管响应可能不同。
服务器端(主)效果必须相同。 RFC允许响应不同。特别是在DELETE的情况下,通常情况是成功删除通常会导致204 No Content
,并且404 Not Found
会重复删除。
虽然答案不必相同,但如果它们是有帮助的话,它仍然是有用的。这简化了客户端逻辑。客户端可以假设重复调用具有相同的效果,因此它应该能够使用相同的代码处理它。 DELETE返回204或404的上述异常非常常见(因为这简化了服务器逻辑)。其他例外情况很少见,只有在有充分理由的情况下才能进行。
严格来说,POST和PATCH操作不需要是幂等的。特别是对于PATCH,它可能会有所帮助。
POST操作意味着不是幂等的。或者反过来说:如果你有一个不能使幂等的操作,它应该是一个POST操作。
说到标准和REST:用于您提到的目的的REST资源应该如下所示:
GET /messages/{messageId}/allowed-users
返回允许的用户列表。请注意,表示列表的资源以复数形式命名(因此messages
而不是message
)。
PUT /messages/{messageId}/allowed-users/{userId}
将新用户添加到允许的用户列表中。
DELETE /messages/{messageId}/allowed-users/{userId}
撤销先前给出的权利。
所有这些操作都应该是幂等的。
使用POST操作如下所示:
POST /messages/{messageId}/allowed-users
{
"userId": "1324"
}
POST将新元素添加到类似列表的资源中。你不需要使这个幂等,但在这种情况下我认为是可取的。
您可以将其他结果代码作为标题或结果对象返回。就像你提到的那样。但如果您愿意:有些人已经详细考虑了这一点,并提出了problem-detail。