可以用POST HTTP方法替换GET,PUT和PATCH吗?

时间:2019-08-22 07:20:01

标签: rest http restful-url

POST,PUT,PATCH和GET都不同。幂等性和安全性是关键的改变者。 在编写RESTFul API时,我遇到了有关何时何地使用一种HTTP方法的指南。由于我将Java用于后端实现,因此我可以控制持久性数据上HTTP方法的行为。 例如,现在可以将GET v1 / book / {id}替换为POST v1 / book(正文中带有“ id”),并使用该ID可以对db进行查询,以获取该特定书。 (假设具有该ID的书已经存在)。 同样,我可以使用POST本身来实现PATCH和PUT的工作。

现在,要问的是,为什么我们可以控制后端的幂等性和安全行为,为什么几乎每次都不会使用POST来代替GET,PUT和PATCH?

或者,这仅仅是RESTFul文档中提到的指南,还是Roy fielding提出的准则,我们所有人都盲目地遵循?即使是这样的指导原则,其背后的主要思想是什么?

https://restfulapi.net/rest-put-vs-post/

https://restful-api-design.readthedocs.io/en/latest/methods.html

https://www.keycdn.com/support/put-vs-post

以上资源仅提及所有方法的作用或它们的区别。文章提到的工作方式就好像它们是一些准则一样,在线文档都没有说出背后的原因。

没有人说,如果我使用POST而不是PUT,PATCH和GET,会有什么副作用? (因为我可以在后端控制他们的行为)

3 个答案:

答案 0 :(得分:1)

Http方法的设计方式是每种方法都承担一些责任。我要说的是,REST是标准,不是约定,而是义务。约定并不强调我们要遵守规则,但是它们是为改进我们的代码而设计的。您可以调整事物并以您的方式使用它们,但这是一个坏主意。就像在这种情况下,如果您使用一种方法执行所有这三个动作,将会在代码中造成极大的混乱(因为POST的简单定义是创建一个对象,而这是每个人都可以理解的),并且还会降低我们的编码标准。 我强烈不建议将三种方法替换为一种。

答案 1 :(得分:0)

如果执行此操作,则不能说您正在“编写RESTFul API”。 谁知道RESTFul标准,都会对您的api的行为感到困惑。 如果您符合标准,那么您的生活将会更轻松。

毕竟,您的方法没有真正的好处。

答案 2 :(得分:0)

HTTP是一种传输协议,顾名思义,HTTP负责通过线与远程系统之间的数据传输,例如文件或db条目。在0.9版中,您基本上只能使用GET操作,而在HTTP 1.0中,几乎所有当前操作都已添加到规范中。

每种方法都可以实现自己的目的。 POST,即按照服务器自身的语义处理有效负载,无论它们是什么。理论上,它可以用于检索,更新或删除内容。但是,对于客户端来说,基本上还不清楚服务器实际上是如何处理有效负载的。无法保证使用该方法调用URI是否安全(更改远程资源)是否安全。想想一个搜寻器,它只是调用它找到的任何URI,而链接之一就是订单链接或执行付款过程的链接。您是否真的希望搜寻器触发您的流程之一?规范非常清楚,如果发生类似情况,则客户不得对此负责。因此,如果某个爬网程序订购了1万个产品作为您的链接之一,并且确实触发了该过程,并且该产品是在该过程中创建的,则您无法向该爬网程序的维护者要求退款。

此外,默认情况下,GET操作的响应是可缓存的。因此,如果您在一定的时间内两次调用相同的资源,则很有可能不需要再次获取该资源(第二次),因为可以从缓存中重新使用该资源。如果使用得当,可以大大减少服务器上的负载。

您已经提到Fielding和REST。 REST是一种体系结构样式,如果您有许多不同的客户端连接到不受控制的服务,则应使用REST。许多所谓的REST API并未遵循REST,因为它们遵循更简单,更实用的RPC方法以及诸如Swagger之类的外部文档。 REST的主要重点是将客户端与服务器分离,从而使服务器可以自由发展,而不必担心破坏客户端。另一方面,客户对变化的适应能力更强。

Fielding仅添加了few constraints REST体系结构必须遵守的内容。其中之一是support for caching。尽管Fielding后来写了引人注目的blog-post,但他在其中解释了API设计人员在调用其API REST之前必须考虑的事项。只有严格遵守所有约束条件,才能实现真正的去耦。如果只有一个客户违反了这些前提条件,那么它将根本无法从REST中受益。

REST的主要前提是(并且应该始终是):Server告诉客户端他们需要什么,而客户端只使用它们所提供的服务。在可浏览的Web(REST的大表亲)中,服务器将教客户端,即服务器希望通过HTML通过Web窗体通过HTML获得的数据,并使用链接关系名称注释链接,以向浏览器提示何时调用该URI。 。在网页上,垃圾桶图标可能指示分配,而铅笔图标可能指示编辑链接。这种视觉提示也称为affordacne。这种视觉提示可能不适用于机器对机器的通信,尽管这些能力可能会暗示它们可能提供的其他内容。考虑一下带有preload注释的样式表。在HTTP 2中,即可以尝试将这种资源由服务器推送,或者在HTTP 1.1中,浏览器可以在该页面仍被解析以加快速度的同时,已经加载该样式表。为了获得对这些含义的广泛了解,应将这些值标准化为IANA。通过custom extensions或诸如microformats之类的某些dublin core,您可以添加新的关系名称,这些名称对于普通情况而言太特定,但对于域本身而言却是公共的。

media-types客户端和服务器进行协商也是如此。与仅由一家公司使用的量身定制的媒体类型相比,一种通用的媒体类型可能会得到更广泛的接受。这里的主要目的是达到可以将相同的媒体类型重新用于各种区域和API的地步。 REST的愿景是拥有最少数量的能够与大量服务器或API进行交互的客户端,类似于能够与几乎所有网站进行交互的浏览器。

您在REST中的最终目标是为您设置一个following an interaction protocol用户,这可能类似于执行订购过程或玩文字游戏,或者没有。通过给客户选择,它将经过一定的过程,可以很容易地描述为状态机。它遵循一种应用程序驱动的协议,即遵循引起客户注意的URI,并返回通过诸如表示形式的形式学习的数据。由于或多或少应该只使用标准化的表示形式,因此不需要有关如何与API交互的带外信息。

尽管实际上,许多企业并不真正关心那些可以在短短几年内成功发展的,可以自由发展的,持久的API。他们通常也不太在乎是否使用适当的HTTP操作还是不受HTTP规范的约束(即使用HTTP GET请求发送有效载荷)。他们的主要目的是完成工作。因此,实用主义通常会胜过设计,因为如此多的开发人员会遵循短暂的成功之路,后来不得不善于工作,这通常很麻烦,因为API现在是其业务的驱动因素,因此他们无法更改无需重新修改整个设计。

  

...当我们可以控制后端的幂等性和安全行为时,为什么几乎每次都不会使用POST来代替GET,PUT和PATCH?

服务器可能知道请求是幂等的,但客户端却不是。诸如safeidempotency之类的属性对客户端来说是允许的。服务器是否满足这些是另一回事。如果出现临时连接问题,客户应如何得知发送的付款请求是否到达服务器并且响应刚刚丢失或初始请求根本没有到达服务器? PUT请求确实保证了幂等性。即如果您在网络出现问题时再次提交相同的请求,则不希望重复订购相同的商品。尽管也可以通过POST发送相同的请求,并且服务器足够聪明以至于无法再次处理该请求,但是客户端不知道服务器的行为,除非对其进行了外部记录,这又以某种方式再次违反了REST原则。因此,换句话说,此类属性或多或少是对客户端的承诺,对服务器的承诺则较少。