虽然HTTP 1.1规范似乎允许在邮件正文DELETE请求时,它似乎表明,服务器应该忽略它,因为有没有它定义的语义。
4.3消息体
服务器应该阅读和任何请求转发消息体; 如果请求方法不包括用于一个实体主体定义的语义,则该消息体应该被处理请求时忽略。
我已经审查了SO内外有关这个主题的几个相关的讨论,如:
- 为允许的HTTP DELETE请求的实体的身体吗?
- HTTP请求方法的有效载荷
- HTTP GET请求与身体
大多数讨论似乎一致认为在DELETE提供邮件正文可能被允许 ,但一般不建议使用。
此外,我注意到在越来越多的改进似乎越来越登录这些库,以支持DELETE请求主体的各种HTTP客户端库的趋势。 大多数图书馆似乎成人之美,虽然偶尔有初步阻力的一点点。
我用例要求在DELETE增加了一些必需的元数据(例如“理性”进行删除,以删除所需的一些其他元数据)。 我已经考虑了以下选项,其中没有一个似乎完全适当的,内嵌HTTP规范和/或REST的最佳做法:
- 邮件正文 -该规范表明对DELETE没有语义值的邮件正文; 通过HTTP客户端不完全支持; 没有标准的做法
- 自定义HTTP头 -需要自定义标题通常是对标准的做法 ; 使用起来与我的API,其中没有需要自定义标头的其余部分不一致; 此外,可没有好HTTP响应(总共大概一个单独的问题)表示坏习惯头值
- 标准HTTP标头 -无标准头是适当的
- 查询参数 -添加查询实际上PARAMS改变Request-URI中被删除; 对标准的做法
- POST方法 - (例如
POST /resourceToDelete { deletemetadata }
)POST未用于删除语义的选择; POST实际上代表希望的相反动作(即POST创建资源下属;但我需要删除该资源) - 多个方法 -拆分DELETE请求分成两个操作(例如删除PUT的元数据,然后删除)分割一个原子操作分为二,潜在地使不一致的状态。 删除原因(和其他相关的元数据)都没有资源表示本身的一部分。
我的第一选择可能是使用邮件正文,第二个自定义的HTTP报头; 然而,正如所指出的,也有一些缺点,以这些方法。
是否有任何建议或最佳实践内嵌REST / HTTP标准包括DELETE请求,例如必需的元数据? 有没有,我还没有考虑任何其他的选择吗?
尽管取得了一些建议不使用在邮件正文中DELETE请求,这种方法可能在某些情况下,使用适当的。 这是我们最后使用评估的问题/答案中提到的其他选项后,与消费者服务的合作后的做法。
虽然使用的消息体的不理想,没有其他的选择是完全拟合无论是。 请求主体DELETE使我们能够轻松,清晰地周围添加这是陪DELETE操作需要额外的数据/元数据的语义。
我仍然开放给其他的想法和讨论,但希望结束对这一问题的循环。 我感谢大家的思想和关于这个主题的讨论!
你似乎需要的是两件事情,这两者都不是一个纯粹的一个DELETE
:
- 你有两个业务,一个
PUT
的删除原因后跟一个DELETE
的资源。 一旦删除,资源的内容不再对任何人访问。 在“理由”不能包含一个超链接到已删除的资源。 要么, - 您正在试图改变从资源
state=active
于state=deleted
使用DELETE
方法。 与国家资源=删除是由你的主要API忽略,但可能仍然是可读,以管理员或某人数据库访问。 这是允许的- DELETE
没有删除后台数据的资源,只删除那个URI公开的资源。
这需要在邮件正文的任何操作DELETE
请求可以被分解为它的最一般的,一个POST
做所有的邮件正文和必要的任务DELETE
。 我认为没有理由打破HTTP的语义。
鉴于你的情况,我会采取下列方法之一:
- 发送PUT或者PATCH:我推断出删除操作是虚拟的,由需要删除的本质原因。 因此,我认为更新通过PUT / PATCH操作记录是一种有效的方法,即使它不是一个DELETE操作本身。
- 使用查询参数 :资源URI不被改变。 其实,我觉得这也是一个有效的方法。 您所连结的问题是谈论不允许如果查询参数缺失的删除。 在你的情况,我只想有,如果在查询字符串没有指定的原因是默认的原因。 该资源将仍然是
resource/:id
。 你可以把它发现与每个原因(与资源链接头rel
每个标签来识别的原因)。 - 每使用一个理由单独的终结点 :使用像一个URL
resource/:id/canceled
。 这不实际更改请求URI和绝对不是RESTful的。 同样,链接标题可以使这个发现。
请记住,REST并不是法律或教条。 它认为更重要思想为指导。 所以,当它有道理不按照指导您的问题域,不。 只要确保你的API的消费者被告知的变异。
我建议你包括所需的元数据的URI层次结构本身的一部分。 一个例子(幼稚):
如果您需要删除而不是传递的开始日期和结束日期在身体或查询参数,结构的URI您传递所需的信息作为URI的一部分,这样基于日期范围条目。
如
DELETE /entries/range/01012012/31122012
-删除2012 01月01日之间的所有条目至2012年12月31日
希望这可以帮助。