Http修补方法被认为是非幂等的,并将部分修改应用于资源,
与PUT相反,PUT是幂等的,适用于资源的替换。
(如MDN所述):
HTTP修补程序请求方法将部分修改应用于资源。 HTTP方法只允许完全替换文档。与PUT不同,修补程序不是幂等的,这意味着连续相同的修补程序请求可能具有不同的效果。
但是,可以以幂等方式(MDN)实现修补程序:
但是,可以以幂等的方式发出修补程序请求。
修补程序的幂等实现的一个例子是:
path: /contact/:id
method: patch
body {
name: 'John'
}无论提出请求的次数如何,资源都将保持与第一个请求后相同的状态。
由于幂等请求被优化(参考文献):
如果处理和重复GET请求花费的时间太长,客户端可能会自动取消GET请求,因为它们假定GET具有相同的效果(因为GET是幂等的)。但是,对于POST请求,他们不会做同样的事情,因为第一个请求可能已经改变了服务器端的某些状态。
据我所知,这种优化只能应用于http标准认为是幂等的HTTP方法。
因此,我上面写的幂等补丁请求不会被优化。(据我理解,HTTP标准说明补丁是非幂等的,但不禁止将其作为幂等)实现。
因为PUT被HTTP标准认为是幂等的。它是否倾向于使用/contact/:id修补程序请求作为PUT (以获得上述优化)?
更新1
我可以将请求修改为PUT,并在服务器中实现它,使其只更新在请求的有效负载中发送的属性,而忽略未发送的属性。通过这种方式,我执行了PUT请求,它以幂等的方式修改了部分资源,并将进行优化,而不是替换整个资源。如果资源非常大,而我想做的更改非常小,那么如果它是以幂等方式实现的,那么每次使用PUT不是更好吗?
这就引出了标题:资源的幂等部分修改更好地实现为PUT而不是修补程序?
更新2 :
HTTP幂等部分修改没有像PUT那样更好地实现的原因是:违背了REST的体系结构设计
随之而来的一些缺点是:
可能还有更多的缺点不坚持其余的建筑风格.
但是,如果我们从性能的角度来看这一点,如果请求是幂等的,则部分PUT更新会更好(因为它得到了上面提到的优化)。
我很高兴听到一些更多的理由出现在我的脑海中:)。
谢谢
发布于 2019-02-02 13:39:02
据我了解,HTTP标准声明修补程序是非幂等的,但不禁止将其作为幂等函数来实现。
这是正确的。更确切地说,标准不能保证幂等语义。
资源的幂等部分修改是否更好地实现为PUT而不是修补程序?
“视情况而定”。
是的,如果使用PUT,那么泛型组件将能够识别服务器承诺对请求进行幂等处理,因此自动重新发送消息是安全的(例如,如果我们超时等待响应到达)。
对于修补程序,您不会得到相同的行为,因为中间层需要了解修补程序文档媒体类型,并深入了解请求有效负载,试图找出正在发生的事情。
但是..。没有“部分放”这样的东西。如果所需的资源表示非常大,并且您想要进行的更改非常小,那么发送一个补丁文档,而不是发送完整的表示,可能会有很大的意义。
这一选择可以归结为对问题的权衡--你有哪些问题是最重要的,哪些问题可以忽略。
为什么没有这样的东西呢?
因为HTTP语义并不是这样定义的。RFC 7231
PUT方法请求创建目标资源的状态或将其替换为由请求消息有效负载中包含的表示定义的状态。给定表示的成功放置将意味着后续的GET在同一目标资源上将导致在200 (OK)响应中发送一个等效的表示。
PUT并不意味着“对此请求应用幂等处理”。它的意思是替换;类似于在文件系统或变量集上覆盖文件的东西。
请记住,统一接口是REST约束之一--它允许我们使用通用组件以标准方式进行通信。
如果您想要幂等的部分替换,并遵守REST约束,那么您要做的就是为一个新方法创建一个规范。有一个定义良好的流程和一个注册表,您可以在其中查找已经通过该过程的方法的标准。
定义了方法之后,组件提供程序可以决定是否选择并支持您的新标准。
用另一种方式表达这种想法:在控制客户端和服务器的情况下,在消息中嵌入自定义语义没有什么问题。但是如果你要用一个标准的方法类型去做,那么你应该使用POST --因为这是泛型组件对正在发生的事情做出最少假设的方法。
https://stackoverflow.com/questions/54493395
复制相似问题