我正在编写一个 REST API,我希望允许具有适当权限的经过身份验证的用户通过此 API 上传文件。我想我会用一个PUT
端点来处理这个问题。我想包括一个故障保护,其中请求将被拒绝400
-如果资源已经存在并且用户没有通过查询指定应该覆盖该资源(即,家庭错误)PUT https://my.server.com/api/files/path/to/file.txt?overwrite=1
).
PUT 的 HTTP/1.1 RFC 文档 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6建议允许这种情况:
如果现有资源被修改,则应发送 200(OK)或 204(无内容)响应代码以指示请求成功完成。如果无法使用 Request-URI 创建或修改资源,则应给出反映问题性质的适当错误响应。
但我对幂等性的概念很着迷。规范说 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2:
方法还可以具有“幂等性”属性,因为(除了错误或过期问题)N > 0 个相同请求的副作用与单个请求的副作用相同。方法 GET、HEAD、PUT 和 DELETE 共享此属性。此外,方法 OPTIONS 和 TRACE 不应该有副作用,因此本质上是幂等的。
然而,多个请求的序列也可能是非幂等的,即使按该序列执行的所有方法都是幂等的。 (如果整个序列的单次执行始终产生不会因重新执行该序列的全部或部分而更改的结果,则序列是幂等的。)例如,如果序列的结果依赖于某个序列,则该序列是非幂等的。稍后以相同顺序修改的值。
根据定义,从不产生副作用的序列是幂等的(前提是没有在同一组资源上执行并发操作)。
我无法理解这一点,因为它适用于我的场景。如果PUT https://my.server.com/myfile.txt
返回一个201 Created
第一次运行,然后403 Forbidden
or 409 Conflict
仅仅因为文件已经存在而在后续请求中不执行任何其他操作就出现错误,这是否违反了幂等性的概念?必须将查询附加到 URI 上以绕过故障保护是否会违反幂等性?
这是关于幂等性的常见思维错误。
该规则的要点不是多个相同的请求得到相同的响应。
该规则的要点是,如果多次发送相同的请求,则服务器的状态与仅发送一次相同。
因此,如果您发送相同的请求两次,第二个请求将出错并被忽略,但服务器上的状态仍然与仅发送第一个请求相同。
更新后的 HTTP 标准有一个有趣的笔记 https://www.rfc-editor.org/rfc/rfc7232#section-3.1 though:
源服务器不得执行请求的方法,如果接收到
If-Match 条件评估结果为 false;相反,源服务器
必须以 a) 412(前提条件失败)状态代码进行响应
或 b) 2xx(成功)状态代码之一(如果源服务器
已验证正在请求状态更改并且最终
状态已经反映在目标的当前状态中
资源(即用户代理请求的更改已经
成功了,但用户代理可能不知道它,也许
因为先前的响应丢失或进行了兼容的更改
由其他一些用户代理)。在后一种情况下,源服务器
不得在响应中发送验证器标头字段,除非可以
验证该请求是否与之前的更改重复
由同一用户代理创建。
即使该段落特定于使用If-Match
标题,它也可能适用于这里。也许你只想回来201 Created
如果您可以检测到发送了完全相同的请求。不过,这对你的问题来说有点题外话。
顺便说一句,你should使用条件标头而不是?overwrite=1
。如果你明确地don't如果想要允许客户端更新已创建的资源,客户端可以简单地包括:
If-None-Match: *
然后你的服务器就可以返回412 Precondition Failed
,向客户端表明该资源是之前创建的。此外,如果您想强制客户端始终包含此标头,您可以使用428 Precondition Required
告诉客户。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)