虽然HTTP 1.1 spec似乎在<{3}}请求上允许消息正文,但它似乎表明服务器应该忽略它,因为它没有定义的语义。
4.3邮件正文
服务器应该在任何请求中读取和转发消息体;如果 请求方法不包含实体主体的定义语义, 那么在处理请求时应该忽略message-body。
我已经在SO及其他方面回顾了有关此主题的几个相关讨论,例如:
大多数讨论似乎都同意,在DELETE上提供邮件正文可能允许,但通常不建议这样做。
此外,我注意到各种HTTP客户端库中的趋势,这些库中似乎记录了越来越多的增强功能,以支持DELETE上的请求主体。大多数图书馆似乎都有责任,尽管偶尔会有一些初步阻力。
我的用例要求在DELETE上添加一些必需的元数据(例如删除的“原因”,以及删除所需的一些其他元数据)。我考虑了以下选项,其中任何一个看起来都不合适,并且与HTTP规范和/或REST最佳实践内联:
POST /resourceToDelete { deletemetadata }
)POST不是删除的语义选项; POST实际上代表了所需的相反的操作(即POST创建资源下属;但我需要删除资源)我的第一个偏好可能是使用消息体,第二个是自定义HTTP头;但是,如上所述,这些方法存在一些缺点。
是否有任何与REST / HTTP标准一致的建议或最佳实践,以便在DELETE请求中包含此类必需的元数据?还有其他我没有考虑的替代方案吗?
答案 0 :(得分:36)
尽管有些建议不要将消息体用于DELETE请求,但这种方法可能适用于某些用例。这是我们在评估问题/答案中提到的其他选项以及与服务的消费者合作之后最终使用的方法。
虽然消息体的使用并不理想,但其他选项都不是完全适合的。请求体DELETE允许我们轻松,清晰地添加伴随DELETE操作所需的其他数据/元数据的语义。
我仍然对其他想法和讨论持开放态度,但想要关闭这个问题的循环。我感谢大家对这个主题的想法和讨论!
答案 1 :(得分:11)
你似乎想要的是两件事之一,它们都不是纯粹的DELETE
:
PUT
后跟资源的DELETE
。删除后,任何人都无法再访问该资源的内容。 “原因”不能包含指向已删除资源的超链接。或者,state=active
方法将资源从state=deleted
更改为DELETE
。主API会忽略state = deleted的资源,但对于管理员或具有数据库访问权限的人员可能仍然可以读取。允许这样做 - DELETE
不必删除资源的后备数据,只删除在该URI上公开的资源。任何需要DELETE
请求上的邮件正文的操作都可以分解为最常见的,POST
来执行邮件正文的所有必要任务,以及{{1 }}。我认为没有理由打破HTTP的语义。
答案 2 :(得分:7)
鉴于你的情况,我会采取以下方法之一:
resource/:id
。您可以使用资源上的链接标头为每个原因使其可被发现(每个原因都带有rel
标记以确定原因。)resource/:id/canceled
的网址。这确实改变了Request-URI,绝对不是RESTful。同样,链接标题可以使其被发现。请记住,REST不是法律或教条。将其视为指导。因此,如果不遵循问题域的指导是有意义的,请不要这样做。只需确保您的API使用者了解差异。
答案 3 :(得分:0)
我建议您将所需的元数据作为URI层次结构本身的一部分。一个例子(天真):
如果您需要根据日期范围删除条目,而不是在正文中作为查询参数传递开始日期和结束日期,请构造URI,以便将所需信息作为URI的一部分传递。< / p>
e.g。
DELETE /entries/range/01012012/31122012
- 删除2012年1月1日至2012年12月31日期间的所有参赛作品
希望这有帮助。