为什么 HTTP PATCH 方法不是幂等的及其延伸
幂等性
首先来看什么是幂等性,根据 rfc2616(Hypertext Transfer Protocol – HTTP/1.1) 文档第 50 页底部对 Idempotent Methods 的定义:
Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
翻译过来也就是:相同的请求执行多次和执行一次的副作用是一样的。
段落接下来就给出了具有幂等性的方法:
The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.
可以看出,GET,HEAD,PUT,DELETE,OPTIONS 和 TRACE 方法都是幂等的。
PUT 和 PATCH
根据约定( Convention ),PUT 方法用于更新数据,PATCH 方法也用于更新数据,为什么 PUT 方法是幂等的而 PATCH 方法不是幂等的呢?我们继续研究文档(第54页):
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.
PUT 方法将请求所包含的实体存储在所提供的 Request-URI 下。如果该 URI 指代一个已经存在的资源,那么请求中的实体应该被视为保存在原服务器上的实体的修改版本。如果 Request-URI 没有指向一个现有资源,并且该 URI 可以被发送请求的用户代理定义为新资源,则原服务器可以使用该 URI 来创建资源。
这里说的很明白了,PUT 用做更新操作的时候是提交一整个更新后的实体,而不是需要修改的实体中的部分属性。当 URI 指向一个存在的资源,服务器要做的事就是查找并替换。
接下来看 PATCH(PATCH 方法在原文档中没有找到相关描述,后来发现在另一个 RFC 里面 - RFC5789):
The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request-URI. The set of changes is represented in a format called a “patch document” identified by a media type. If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc.
PATCH 方法请求将一组描述在请求实体里的更改应用到 Request-URI 标志的资源。这组更改以称为 “补丁文档” 的格式(该格式由媒体类型标志)表示,如果 Request-URI 未指向现有资源,服务器可能根据补丁文档的类型(是否可以在逻辑上修改空资源)和权限等来创建一个新资源。
所以可以知道 PATCH 请求中的实体是一组将要应用到实体的更改,而不是像 PUT 请求那样是要替换旧资源的实体,但是这并没有解决 PATCH 方法为什么不是幂等的问题。不着急,继续读,接下来就给出了 PUT 和 PATCH 的区别:
The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; i.e., new resources may be created, or existing ones modified, by the application of a PATCH.
PUT 和 PATCH 请求的区别体现在服务器处理封闭实体以修改 Request-URI 标志的资源的方式。在一个 PUT 请求中,封闭实体被认为是存储在源服务器上的资源的修改版本,并且客户端正在请求替换存储的版本。而对于 PATCH 请求,封闭实体中包含了一组描述当前保留在源服务器上的资源应该如何被修改来产生一个新版本的指令。PATCH 方法影响由 Request-URI 标志的资源,而且它也可能对其他资源有副作用;也就是,通过使用 PATCH,新资源可能被创造,或者现有资源被修改。
以上就是答案。可以理解为,PATCH 请求中的实体保存的是修改资源的指令,该指令指导服务器来对资源做出修改,所以不是幂等的。
可能有点抽象,打个比方:对于存在服务器中的 A 对象有个属性 B 为 1,如果要修改 B 属性为 3,则 PUT 请求是直接将修改过 B 属性的整个新对象发送给服务器查找并替换。而 PATCH 请求是在实体中包含指令 — 将 A 对象中 B 属性的值加 2,那么如果该请求被执行多次的话,B 属性就可能不为 3 了,而 PUT 请求不论执行多少次,B 属性永远都是 3,所以说 PUT 方法是幂等的,而 PATCH 方法不是幂等的。
PUT 和 POST
在看请求相关的帖子的时候,偶尔也会看见争论说使用 PUT 来新增资源,使用 POST 来修改资源,或者说这两个方法差别不大,没必要这么明确分工。上文也提到了 PUT 方法的 URI 指向的资源不存在的时候也可以创建新资源。那到底怎么用,都写到这里了继续是用文档来说话,有关 POST 方法的说明:
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:
- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list or similar group of articles;
- Providing a block of data, such as the result of submitting a form, to a data-handling process;
- Extending a database through an append operation.
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.
POST 方法用于请求源服务器接受请求中的实体作为 Request-URI 所标志的资源的新下级。 POST 方法旨在允许一个统一的方法来涵盖以下功能:
- 现有资源的注释;
- 在公告栏,新闻组,邮件列表或类似文章组中发布消息;
- 提供数据块,例如提交表单的结果,数据处理过程;
- 通过追加操作扩展数据库。
POST方法执行的实际功能由服务器确定,通常依赖于 Request-URI。 发布的实体从属于该 URI,其方式与文件从属于包含它的目录相同,新闻文章从属于发布它的新闻组,或者记录从属于数据库。
PUT 和 POST
在看请求相关的帖子的时候,偶尔也会看见争论说使用 PUT 来新增资源,使用 POST 来修改资源,或者说这两个方法差别不大,没必要这么明确分工。上文也提到了 PUT 方法的 URI 指向的资源不存在的时候也可以创建新资源。那到底怎么用,都写到这里了继续是用文档来说话,有关 POST 方法的说明:
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:
Annotation of existing resources;
Posting a message to a bulletin board, newsgroup, mailing list or similar group of articles;
Providing a block of data, such as the result of submitting a form, to a data-handling process;
Extending a database through an append operation.
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.
POST 方法用于请求源服务器接受请求中的实体作为 Request-URI 所标志的资源的新下级。 POST 方法旨在允许一个统一的方法来涵盖以下功能:
现有资源的注释;
在公告栏,新闻组,邮件列表或类似文章组中发布消息;
提供数据块,例如提交表单的结果,数据处理过程;
通过追加操作扩展数据库。
POST方法执行的实际功能由服务器确定,通常依赖于 Request-URI。 发布的实体从属于该 URI,其方式与文件从属于包含它的目录相同,新闻文章从属于发布它的新闻组,或者记录从属于数据库。
相关文章:
为什么 HTTP PATCH 方法不是幂等的及其延伸
幂等性 首先来看什么是幂等性,根据 rfc2616(Hypertext Transfer Protocol – HTTP/1.1) 文档第 50 页底部对 Idempotent Methods 的定义: Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the…...
13 Day:实现内核线程
前言:我们昨天完成了内核的内存池以及内存管理程序,今天我们要揭开操作系统多任务执行的神秘面纱,来了解并实现一个多任务的操作系统。 一,实现内核线程 在聊线程之间我们先聊聊处理器吧,众所周之现在我们的CPU动不动…...
GPU服务器安装显卡驱动、CUDA和cuDNN
GPU服务器安装cuda和cudnn1. 服务器驱动安装2. cuda安装3. cudNN安装4. 安装docker环境5. 安装nvidia-docker25.1 ubuntu系统安装5.2 centos系统安装6. 测试docker容调用GPU服务1. 服务器驱动安装 显卡驱动下载地址https://www.nvidia.cn/Download/index.aspx?langcn显卡驱动…...
结构体变量
C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体(structre)。 在程序中建立一个结构体类型: 1.结构体 建立结构体 struct Student { int num; //学号为整型 char name[20]; //姓名为字符串 char se…...
Java 多态
文章目录1、多态的介绍2、多态的格式3、对象的强制类型转换4、instanceof 运算符5、案例:笔记本USB接口1、多态的介绍 多态(Polymorphism)按字面意思理解就是“多种形态”,即一个对象拥有多种形态。 即同一种方法可以根据发送对…...
九龙证券|一夜暴跌36%,美股走势分化,标普指数创近2月最差周度表现
当地时间2月10日,美股三大指数收盘涨跌纷歧。道指涨0.5%,标普500指数涨0.22%,纳指跌0.61%。 受国际油价明显上升影响,动力板块领涨,埃克森美孚、康菲石油涨超4%。大型科技股走低,特斯拉、英伟达跌约5%。热门…...
【数据库】 mysql用户授权详解
目录 MySQL用户授权 一,密码策略 1,查看临时密码 2,查看数据库当前密码策略: 二, 用户授权和撤销授权 1、创建用户 2,删除用户 3,授权和回收权限 MySQL用户授权 一,密码策略…...
【性能】性能测试理论篇_学习笔记_2023/2/11
性能测试的目的验证系统是否能满足用户提出的性能指标发现性能瓶颈,优化系统整体性能性能测试的分类注:这些测试类型其实是密切相关,甚至无法区别的,例如几乎所有的测试都有并发测试。在实际中不用纠结具体的概念。而是要明确测试…...
C语言(输入printf()函数)
printf()的细节操作很多,对于现阶段的朋友来说,主要还是以理解为主。因为很多的确很难用到。 目录 一.转换说明(占位符) 二.printf()转换说明修饰符 1.数字 2.%数字1.数字2 3.整型转换字符补充 4.标记 -符号 符号 空格符…...
Zabbix 构建监控告警平台(四)
Zabbix ActionZabbix Macros1.Zabbix Action 1.1动作Action简介 当某个触发器状态发生改变(如Problem、OK),可以采取相应的动作,如: 执行远程命令 邮件,短信,微信告警,电话 1.2告警实验简介 1. 创建告警media type&…...
2004-2019年285个地级市实际GDP与名义GDP
2004-2019年285个地级市实际GDP和名义GDP 1、时间:2004-2019年 2、范围:285个地级市 3、说明:GDP平减指数采用地级市所在省份当年平减指数 4、代码: "gen rgdp gdp if year 2003 gen rgdp gdp if year 2003" re…...
Node.js笔记-Express(基于Node.js的web开发框架)
目录 Express概述 Express安装 基本使用 创建服务器 编写请求接口 接收请求参数 获取路径参数(/login/2) 静态资源托管-express.static(内置中间件) 什么是静态资源托管? express.static() 应用举例 托管多个静态资源 挂载路径前缀…...
力扣sql简单篇练习(十五)
力扣sql简单篇练习(十五) 1 直线上的最近距离 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT min(abs(p1.x-p2.x)) shortest FROM point p1 INNER JOIN point p2 ON p1.x <>p2.x1.3 运行截图 2 只出现一次的最大数字 2.1 题目内容 2…...
浅谈动态代理
什么是动态代理?以下为个人理解:动态代理就是在程序运行的期间,动态地针对对象的方法进行增强操作。并且这个动作的执行者已经不是"this"对象了,而是我们创建的代理对象,这个代理对象就是类似中间人的角色,帮…...
Idea超好用的管理工具ToolBox(附带idea工具)
文章目录为什么要用ToolBox总结idea管理安装、更新、卸载寻找ide配置、根路径idea使用准备工作配置为什么要用ToolBox 快速轻松地更新,轻松管理您的 JetBrains 工具 安装自动更新同时更新插件和 IDE回滚和降级通过下载补丁或一组补丁而不是整个包,节省维护 IDE 的…...
Spring 中 ApplicationContext 和 BeanFactory 的区别
文章目录类图包目录不同国际化强大的事件机制(Event)底层资源的访问延迟加载常用容器类图 包目录不同 spring-beans.jar 中 org.springframework.beans.factory.BeanFactoryspring-context.jar 中 org.springframework.context.ApplicationContext 国际…...
情人节有哪些数码好物值得送礼?情人节实用性强的数码好物推荐
转瞬间,情人节快到了,大家还在为送什么礼物而烦恼?在这个以科技为主的时代,人们正在享受着科技带来的便利,其中,数码产品也成为了日常生活中必不可少的存在。接下来,我来给大家推荐几款比较实用…...
java中flatMap用法
java中map是把集合每个元素重新映射,元素个数不变,但是元素值发生了变化。而flatMap从字面上来说是压平这个映射,实际作用就是将每个元素进行一个一对多的拆分,细分成更小的单元,返回一个新的Stream流,新的…...
【MySQL Shell】8.9.2 InnoDB ClusterSet 集群中的不一致事务集(GTID集)
AdminAPI 的 clusterSet.status() 命令警告您,如果 InnoDB 集群的 GTID 集与 InnoDB ClusterSet 中主集群上的 GTID 集不一致。与 InnoDB ClusterSet 中的其他集群相比,处于此状态的集群具有额外的事务,并且具有全局状态 OK_NOT_CONSISTENT 。…...
logstash毫秒时间戳转日期以及使用业务日志时间戳替换原始@timestamp
文章目录问题解决方式参考问题 在使用Kibana观察日志排查问题时发现存在很多组的timestamp 数据一样,如下所示 详细观察内部数据发现其中日志数据有一个timestamp字段保存的是业务日志的毫秒级时间戳,经过和timestamp数据对比发现二者的时间不匹配。经…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
