PUT POST 具有幂等性 (REST)

2023-11-25

我不太明白 HTTP 动词是如何定义为幂等的。我读到的只是 GET 和 PUT 是幂等的。 POST 不是幂等的。但是您可以使用 POST 创建一个不会更改任何内容(例如在数据库中)的 REST API,或者为 PUT 创建一个在每次调用时都会更改的 REST API。

当然,这可能是错误的做法,但如果可以做到,为什么在实现时将 PUT 标记为幂等(或将 POST 标记为非幂等)?我并不是在挑战这个想法,我可能遗漏了一些东西,我要求澄清我的理解。

EDIT:

我想提出问题的一种方法是:如果我使用 PUT 进行非幂等调用并使用 POST 来执行此操作,会出现什么问题?


您正确地指出,HTTP 协议中没有任何固有的内容可以强制执行方法/动词的幂等属性,例如PUT and DELETE。 HTTP,作为无状态协议,不保留用户提出的每个请求的信息或状态;每个请求都被视为独立的。

引用维基百科上的HTTP 方法的幂等属性(强调我的):

请注意,方法是否幂等不是由 协议或网络服务器。写一个网页是完全可以的 应用程序,其中(例如)数据库插入或其他 非幂等操作由 GET 或其他请求触发。忽略 然而,这一建议可能会导致不良后果, 如果用户代理认为重复相同的请求是安全的 事实并非如此。

所以,是的,有可能偏离传统的实现,并推出诸如不改变的 POST 实现、非幂等 PUT 等之类的东西,可能不会出现重大的、危及生命的技术问题。但您可能会冒着让使用您的 Web 服务的其他程序员感到不安的风险,因为他们认为您不知道自己在做什么。

这里有一个重要的引述RFC2616关于 HTTP 方法safe(强调我的):

实施者应该意识到软件代表用户 他们通过互联网进行互动,并且应该小心允许 用户了解他们可能采取的任何可能会产生影响的操作 对自己或他人有意想不到的意义。

特别是,习俗已经确定 GET 和 HEAD 方法不应该具有采取行动的意义 除了检索之外。这些方法应该被认为是“安全的”。 这允许用户代理代表其他方法,例如 POST、PUT 并以特殊方式删除,以便让用户知道的 正在请求执行可能不安全的操作。

当然,也无法保证服务器不会 执行 GET 请求时会产生副作用;在 事实上,一些动态资源认为这是一个功能。重要的 这里的区别是用户没有请求副作用,所以 因此不能对他们负责。

UPDATE: 正如所指出的Julian,RFC 2616 已被 RFC 7231 取代。这是相应的部分.

因此,当您将 Web 服务发布为PUT方法,然后我提交一个如下所示的请求:

PUT /users/<new_id> HTTP/1.1
Host: example.com

我期望创建一个新的用户资源。同样,如果我的请求如下所示:

PUT /users/<existing_id> HTTP/1.1
Host: example.com

我预计相应的现有用户会被更新。如果我通过多次提交表单来重复相同的请求,请不要弹出警告对话框(因为我喜欢既定的约定)。

相反,作为 POST Web 服务的使用者,我期望收到如下请求:

POST /users/<existing_id> HTTP/1.1
Host: example.com

更新相应的现有用户,而请求如下所示:

POST /users/<new_id> HTTP/1.1
Host: example.com

因为 URL 尚不存在而引发错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PUT POST 具有幂等性 (REST) 的相关文章

随机推荐

  • Kubernetes - 没有选择器的服务

    我正在为没有选择器的 Kubernetes 服务而苦苦挣扎 该集群通过 kops 安装在 AWS 上 我有一个包含 3 个 nginx pod 的部署 暴露端口 80 apiVersion apps v1 kind Deployment m
  • 会话的跨子域 cookie 处理?

    是否可以设置一个有效的身份验证 cookie sub1 domain com sub2 domain com 或者每个子域总是需要它自己的 cookie 如果指定要附加到域的 cookie 则可以跨子域使用 cookie domain co
  • 拳击和加宽

    这两者有什么区别呢 我知道拳击正在将原始值转换为引用 什么是扩大 另外 首先应该进行拳击还是应该进行加宽的顺序应该是什么 扩大对拳击和 var args 的胜利 拳击战胜了 var args 引用变量的扩宽取决于继承 因此 Integer
  • 如何使用 Mercurial 子存​​储库来共享组件和依赖项?

    我们使用 C 开发 NET 企业软件 我们正在寻求改进我们的版本控制系统 我以前使用过mercurial 并且一直在我们公司尝试使用它 然而 由于我们开发企业产品 我们非常关注可重用的组件或模块 我一直在尝试使用 Mercurial 的子存
  • UIActivityIndi​​catorView 在 UICollectionViewCell 中不旋转

    我有一个自定义单元格加载在我的集合视图的底部 它唯一的工作是显示活动指示器视图 这在应用程序进行新的工作调用时发生 所以我将它添加到单元格中 如下所示 BBLoaderCell loaderCell collectionView deque
  • 在 d3 中缩放投影是什么意思?

    我知道在 D3 中 尺度是从输入数据值 域 到输出数据值 范围 的数学映射 我知道我可以设置一个比例 将域的输入映射到一个范围 如下所示 var scale d3 scale linear domain 100 500 range 10 3
  • 导出 JasperReports 查询结果

    在我的 Java 项目中 我有很多带有复杂 SQL 查询的 JasperReports 报告 其中包含很多参数 这些报告用于生成包含查询返回的数据的 pdf 文档 这些数据以各种方式分组和格式化 现在我还需要直接导出查询结果 例如 Resu
  • 如何从 Python Pyramid 提供临时文件

    目前 我只是提供这样的文件 view callable def export request response Response content type application csv use datetime in filename t
  • 当 printf 的相应参数不是短/字符时,使用 h 或 hh 长度修饰符是否非法?

    The printf函数族提供了一系列长度修饰符 其中两个是hh 表示一个signed char or unsigned char论点提升为int and h 表示一个signed short or unsigned short论点提升为i
  • PHP 电子邮件正文解码为纯文本

    我正在用 php 绑定一些相同电子邮件的提取内容 但我不能 接着就 随即 body imap body imap o email n I get Pour le r E9cup E9rer il suffit de le t E9l E9c
  • 批量“计数器”

    我正在尝试制作一个批处理文件 每次循环时都会将变量加 1 然后检查该变量是否等于 5 如果不等于 则再次循环 我知道这可能需要一个 while 循环 但我不知道该怎么做 而且我现在只是享受学习 Batch 的乐趣 这是代码 它没有按应有的方
  • C# MySQL like查询不带参数

    我正在使用查询来查找特定字段中的关键字 当我输入 parameter 然后添加带有值的参数时 它不起作用 但是当我直接输入值时 它起作用 任何人都可以帮助我将值作为参数传递给我的请询问 下面是我的代码 这可以工作并检索标题中包含 我的 一词
  • 如何防止使用 JPA 保存子对象?

    我在学校和学生实体之间建立了 OneToMany 关系 我想要做的是 当我保存学校对象时 不要保存或更新学生对象 当然也不要删除它们 当我尝试保存如下所示的学校对象时 它也会更新我的学生对象 但我不希望它们被更新 而只是可连接 有什么办法吗
  • C# 拦截WebBrowser发出的请求

    是否可以拦截所有的请求WebBrowser控制 我想修改每个请求的请求URI 包括图像 脚本 样式表等的请求 有一个活动叫 导航2之前 在发出任何请求之前调用 您可以使用它来修改传出请求
  • 无形状映射中的子类型多态性

    我构建了以下内容 import shapeless import poly object Main def main args Array String object iterateOverHList extends List gt Ite
  • 在未找到匹配项的 OPTIONAL MATCH 之后创建

    我正在尝试编写一个查询 如果另一个关系已经存在 它将创建一些关系 START a node 1 b node 2 c node 3 OPTIONAL MATCH a r1 RELATIONSHIP optional1 OPTIONAL MA
  • 判断CGPoint是否在图像区域内

    我试图弄清楚 CGPoint 是否位于图像的形状内 该图像是一个简单的黑色形状 如下面所附的两个 我想创建一个方法来确定 CGPoint 是否位于该形状的黑色区域内 我认为这需要两件事 1 将图像变成可以用代码读取的东西 不确定这将使用哪种
  • Flask 中的大文件上传

    我正在尝试实现一个烧瓶应用程序来上传文件 该文件可能非常大 比如差不多2G大小 我已经完成了服务器端处理功能 如下所示 app route upload
  • Volley 服务器错误,网络响应为空

    每次我尝试在 Volley 中使用 POST 方法时 都会出现严重错误 我在 getCause 中得到 null 值 在 get Network Response toString 中得到一些默认值 如果我使用 GET 方法 效果很好 我从
  • PUT POST 具有幂等性 (REST)

    我不太明白 HTTP 动词是如何定义为幂等的 我读到的只是 GET 和 PUT 是幂等的 POST 不是幂等的 但是您可以使用 POST 创建一个不会更改任何内容 例如在数据库中 的 REST API 或者为 PUT 创建一个在每次调用时都