首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HTTP和DELETE的优点

HTTP和DELETE的优点
EN

Stack Overflow用户
提问于 2012-10-29 15:58:54
回答 2查看 2.8K关注 0票数 8

所以HTTP规范说HTTP和DELETE应该是幂等的。这意味着,对同一个具有相同主体的URL的多个PUT请求不应该对服务器产生额外的副作用。多个HTTP删除也是如此,如果向同一个URL发送2个或多个DELETE请求,则第二个(或第三个)请求不应返回指示资源已被删除的错误。

但是,在处理了DELETE之后,如何将请求放到URI中呢?它应该返回404吗?

例如,考虑按以下顺序执行以下请求:

  • POST /api/items -创建一个item资源,返回HTTP201和URI /api/items/6
  • PUT /api/items/6 -更新与item #6关联的数据
  • PUT /api/items/6 -只要请求体与以前的PUT相同,就没有副作用
  • 删除/api/items/6 -删除item #6并返回HTTP202
  • DELETE /api/items/6 -没有副作用,也返回HTTP 202
  • GET /api//6-这将返回一个404
  • 放置/api/items/6 -这里应该发生什么? 404? 409?还有什么吗?

那么,PUT是否应该与get并返回404一致,或者像@CodeCaster建议的那样,409是否更合适呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-29 16:02:40

RFC 2616,第9.6节,PUT: POST和PUT请求之间的根本区别反映在请求-URI的不同含义中。POST请求中的URI标识将处理封闭实体的资源。该资源可能是一个数据接受过程,一个通往其他协议的网关,或者是一个接受注释的独立实体。相反,PUT请求中的URI标识与请求一起的实体-- 用户代理知道URI的意图,并且服务器不能试图将请求应用于其他资源。

和:

如果无法使用请求URI创建或修改资源,则应该给出反映问题性质的适当错误响应。

因此,定义“适当”是查看400系列,表明存在客户端错误。首先,我将消除不相关的问题:

  • 400坏请求:由于格式错误的语法,服务器无法理解请求。
  • 401未经授权的:请求需要用户身份验证。
  • 402支付所需的:此代码保留给以后使用。
  • 406不可接受的:请求标识的资源.根据在请求中发送的接受标头,不可接受。
  • 407代理身份验证需要:此代码.指示客户端必须首先使用代理进行身份验证。
  • 408请求超时:客户端在服务器准备等待的时间内没有产生请求。
  • 411长度需要:如果没有定义的内容长度,服务器拒绝接受请求。

那么,我们可以用哪一个呢?

403禁止服务器理解请求,但拒绝满足请求。授权于事无补,不应重复请求。

这种描述实际上非常适合,尽管它通常用于与权限相关的上下文中(如:您可能不.)。

找不到404服务器没有找到任何匹配请求-URI的内容。没有迹象表明这种情况是暂时的还是永久性的。如果服务器通过某种内部可配置机制知道旧资源永久不可用且没有转发地址,则应使用410 (Gone)状态代码。当服务器不希望确切显示请求被拒绝的确切原因或其他响应不适用时,通常使用此状态代码。

这个也是,尤其是最后一行。

405方法不允许请求行中指定的方法不允许用于请求URI标识的资源。响应必须包括一个允许标头,其中包含被请求资源的有效方法列表。

我们无法使用有效的方法进行响应,因为我们目前不希望在此资源上执行任何方法,因此不能返回405。

409冲突冲突最有可能发生在响应PUT请求。例如,如果正在使用版本控制,并且正在放置的实体包括对资源的更改,这些更改与早期(第三方)请求所做的更改相冲突,服务器可能会使用409响应来指示它无法完成请求。在这种情况下,响应实体可能会以响应内容类型定义的格式包含两个版本之间差异的列表。

但是,这假设URI中已经有一个资源(为什么会出现冲突呢?)。

410走了请求的资源在服务器上不再可用,也不知道转发地址。预计这一条件将被视为永久性的。具有链接编辑功能的客户端应在用户批准后删除对请求-URI的引用。如果服务器不知道或无法确定条件是否永久,则应使用状态代码404 (未找到)。

这个也是有道理的。

我曾经编辑过这篇文章几次,当它宣称“使用410或404”时,它被接受了,但现在我认为403也可能适用,因为RFC没有声明403必须与权限相关(但它似乎是由流行的web服务器实现的)。我认为我已经删除了所有其他400码,但请评论(在你投反对票之前)。

票数 11
EN

Stack Overflow用户

发布于 2012-10-30 18:55:01

您的问题有一个未声明的假设前提,即资源必须存在才能成功。这不是一个正确的假设。

规范(RFC2616)的相关部分说:

用户代理知道URI的意图,服务器不能试图将请求应用于其他资源.

规范并没有说,“为了使PUT成功,引用URI上的对象必须已经存在”。

简单的例子是一个通过REST实现的web商店。GET在给定路径上返回对象的表示,而DELETE在给定路径上删除项。这些都很简单。但这篇文章和文章并不难理解。POST可以做任何事情,但是使用POST可以在客户端指定的容器中创建一个对象,并让服务器返回容器中新创建的对象的URI。PUT更受限制;它在给定的URI上为服务器提供对象的表示。对象可能已经存在,也可能不存在。PUT不是替换的同义词。

在我看来,409或410对于PUT是错误的,除非容器本身--你想要放入的东西--不存在。

因此:

代码语言:javascript
复制
POST /container
   ==> returns 200 with `Location:/container/resource-12345`

PUT /container/resource-98928
   ==> returns 201 CREATED or 200 OK

PUT /this-container-does-not-exist/resource-22828282
   --> returns 400

当然,这取决于您是否希望您的服务器允许这些PUT语义。但是,规范中没有任何内容要求您不允许客户端提供他是PUTting的资源的URI。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13125185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档