我的RESTful服务包括表示项ACL的资源。要更新此ACL,客户端会以新ACL作为其实体执行PUT
请求。成功时,PUT
响应实体包含新ACL的已清理的规范版本。
在大多数情况下,HTTP响应状态代码相当明显。成功时200
,403
如果不允许用户编辑ACL,400
如果新ACL格式不正确,404
如果他们尝试设置ACL如果412
标头不匹配,则为{_ 1}}不存在的项目。
然而,有一种情况,正确的HTTP状态代码并不明显。如果经过身份验证的用户使用If-Match
从ACL中删除自己,该怎么办?我们需要表明请求已成功,但他们无法再访问该资源。
我已经考虑在PUT
实体中使用新ACL返回200
,但这没有任何迹象表明他们不再具有PUT
资源的能力。我考虑直接返回GET
,但这并不表示403
成功。我已经考虑将PUT
与303
指向同一资源(后续Location
会给出GET
),但这似乎是对{的误用{1}}鉴于资源尚未移动。
那么什么是“成功的REST HTTP状态代码,因此您不再具有访问权限”?
答案 0 :(得分:3)
200是适当的响应,因为它表示成功(正如任何2xx代码所暗示的那样)。您可以区分用户在响应中缺少权限(或者,如果您不希望,则204可以)。状态代码没有约定未来的请求将返回相同的代码:对PUT的200响应并不意味着后续的GET不能返回403.通常,服务器不应该试图告诉客户如果他们发出特定的话将会发生什么请求。 HTTP客户端应该在它们看起来之前几乎总是跳跃并且准备好处理几乎任何响应代码。
你应该阅读updated description of the PUT method in httpbis;它不仅讨论了200/204的使用,而且还仔细阅读说明,在对PUT的立即响应中返回转换后的表示是不合适的;相反,使用ETag或Last-Modified标头来指示客户端发送的实体是否已转换。如果是,客户端应该发出后续的GET而不是期望发送新的表示以响应PUT,如果没有其他原因而不是沿途更新任何缓存(因为对PUT的响应不可缓存) 。 Section 6.3.1同意:对PUT的响应应该代表行动的状态,而不是资源本身。另请注意,对于新ACL,您必须返回201,而不是200。
答案 1 :(得分:2)
你混淆了两个语义概念,并尝试将它们组合成一个响应代码。
第一个:您在尝试的位置成功创建了ACL。正确的语义响应(在RESTful或非RESTful场景中)是 201 Created 。来自RFC:“请求已经完成并导致创建新资源。”
第二种:执行PUT的用户不再能够访问该资源。这是一个暂时的想法 - 如果更新ACL,或者在下一个请求之前发生了什么变化,该怎么办?用户无权访问任何类型的资源(这包括ACL资源)的想法仅对该请求的范围有用。在执行下一个请求之前,某些内容可能会发生变化。在用户无法访问某项内容的单个请求中,您应返回 403 Forbidden 。
您的PUT方法应该返回201.如果客户担心它是否已经访问,它应该发出后续请求来确定它的状态。
答案 2 :(得分:1)
您可能需要查看HTTP响应代码“204 No Content”(http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html),表示“服务器已完成请求[要从ACL中删除]但不需要返回实体主体,可能想要返回更新的元信息“(这里,由于成功删除)。虽然您不允许使用204返回消息正文,但您可以返回实体标题,指示用户对资源的访问权限的更改。我从Amazon S3获得了这个想法 - 他们在成功的DELETE请求(http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html)上返回204,这似乎与您的情况相似,因为从ACL中移除您自己,您将来阻止了对该资源的访问
答案 3 :(得分:0)
非常有趣的问题:-)这就是为什么我喜欢REST,有时它会让你发疯。阅读w3 http status code definitions我会选择(这当然只是我的拙见)其中之一:
另一方面(刚出现在脑海中),你为什么要引入一个单独的逻辑并区分那个案例而不是200?这个休息是否会从具有UI的某个客户端应用程序中使用?其余的用户应该向最终用户显示弹出窗口“你确定要从ACL中移除自己吗?”在这里,如果您的休息返回200并且只显示一个弹出窗口“您确定要从ACL中删除具有名称的用户吗?”,则可以处理该案例,无需区分这两种情况。如果这个休息将用于某些服务到服务的通信(即,仅从另一个程序调用),为什么要在这里区分这些情况,程序将不关心将从ACL中删除哪个用户。
希望有所帮助。