当前位置: 首页 > 知识库问答 >
问题:

删除请求体的RESTful替代方法

司徒志强
2023-03-14

虽然HTTP 1.1规范似乎允许删除请求上的消息体,但似乎表明服务器应该忽略它,因为它没有定义语义。

4.3消息正文

服务器应该在任何请求上读取和转发消息正文;如果请求方法不包括实体正文的定义语义学,那么在处理请求时应该忽略消息正文。

我已经回顾了关于这个话题的一些相关讨论,比如:

  • 实体实体是否允许HTTP删除请求

大多数讨论似乎一致认为,可以允许在删除时提供消息正文,但通常不建议这样做。

此外,我注意到各种HTTP客户机库中出现了一种趋势,这些库似乎有越来越多的增强功能被记录下来,以支持删除请求主体。大多数图书馆似乎都会这样做,尽管偶尔会遇到一些最初的阻力。

我的用例要求在删除时添加一些必需的元数据(例如,删除的“原因”,以及删除所需的一些其他元数据)。我考虑过以下选项,它们似乎都不完全合适,也不符合HTTP规范和/或REST最佳实践:

  • 消息正文-规范表明DELETE上的消息正文没有语义值;HTTP客户端不完全支持;不是标准做法
  • 自定义HTTP标头-需要自定义标头通常违反标准实践;使用它们与我的API的其余部分不一致,其中没有一个需要自定义标头;此外,没有良好的HTTP响应可用于指示错误的自定义标头值(可能是一个单独的问题)
  • 标准HTTP标头-没有标准标头是合适的
  • 查询参数-添加查询参数实际上会更改正在删除的Request est-URI;针对标准实践
  • POST方法-(例如POST /resourceToDelete{deletemetadata})POST不是删除的语义选项;POST实际上代表了所需的相反操作(即POST创建资源下属;但我需要删除资源)
  • 多种方法-将DELETE请求拆分为两个操作(例如PUT删除元数据,然后DELETE)会将原子操作拆分为两个,从而可能留下不一致的状态。删除原因(和其他相关元数据)不是资源表示本身的一部分。

我的第一个偏好可能是使用消息体,其次是自定义HTTP头;然而,正如所指出的,这些方法也有一些缺点。

对于在删除请求中包含此类必需的元数据,是否有与REST/HTTP标准一致的建议或最佳实践?还有其他我没有考虑过的选择吗?

共有3个答案

彭兴朝
2023-03-14

鉴于你的情况,我会采取以下方法之一:

  • 发送一个PUT或补丁:我推断删除操作是虚拟的,本质上需要一个删除原因。因此,我认为通过PUT/PATCH操作更新记录是一种有效的方法,尽管它本身不是一种删除操作

记住,Rest不是法律或教条。更多地将其视为指导。因此,当不遵循问题领域的指导是合理的时,不要这样做。只需确保您的API消费者了解差异。

胡意致
2023-03-14

你似乎想要的是两件事中的一件,这两件事都不是纯粹的删除:

  1. 您有两个操作,删除原因的PUT,然后是资源的delete。一旦删除,任何人都无法再访问资源的内容。“原因”不能包含指向已删除资源的超链接。或者,
  2. 您正试图使用DELETE方法将资源从state=active更改为state=deleted。state=deleted的资源会被主API忽略,但管理员或具有数据库访问权限的人可能仍然可以读取。这是允许的——DELETE不必擦除资源的备份数据,只需删除在该URI上公开的资源

任何在删除请求中需要消息体的操作,在最一般的情况下可以分为发布删除。我认为没有理由破坏HTTP的语义。

阴靖
2023-03-14

尽管有一些建议不要将消息体用于删除请求,但这种方法在某些用例中可能是合适的。这是我们在评估问题/答案中提到的其他选项,并与服务消费者合作后最终使用的方法。

虽然消息体的使用并不理想,但其他选项也都不完美。请求主体DELETE允许我们轻松、清晰地围绕删除操作所需的其他数据/元数据添加语义。

我仍然愿意接受其他想法和讨论,但我想结束这个问题的循环。我感谢大家对这个话题的思考和讨论!

 类似资料:
  • 我有Java控制器: 并遇到以下问题:警告14068--[nio-8080-exec-3].w.s.m.s.defaultHandlerExceptionResolver:Resolved[org.springframework.web.httpRequestMethodNotSupportedException:Request method'DELETE'not support]它发生在我发送删

  • 我有个问题。当我发送删除请求时,我的Web服务器sinds 403响应。我不想删除请求中的内容,我只需要知道使用的方法是delete。如何配置Web服务器,使其不再发送403条消息?我不想启用WebDAV或类似的东西。我只想知道请求方法是否是DELETE(在我的php文件中,但由于403的原因,它没有被执行)。

  • 在我使用JMeter进行的测试中,创建了一些属性,请参阅以下内容: -----------------------------7d159c1302d0y0 内容-处置:窗体-数据;名称="年龄" 内容-类型:文本/普通;charset=ISO-8859-1 内容-传输-编码:8bit 我想删除属性: 内容-类型:文本/普通;charset=ISO-8859-1 内容传输编码:8bit 我尝试运行下

  • 我有一个angular应用程序,只要我按照以下步骤添加serviceWorker: https://github.com/angular/angular-cli/blob/master/docs/documentation/build.md#service-workerhttps://angular.io/guide/service-worker-getting-started …我的API请求不

  • 每当我尝试使用axios发送删除endpoint的请求时,都会出现以下错误: 通过CORS策略阻止从源http://localhost:3000在http://localhost:8080/api/payment_card/delete/1234123412343433处访问XMLHttpRequest:对预检请求的响应未通过权限改造检查:请求的资源上不存在“Access-Control-Allo

  • 我试图在spring中以XML形式返回对象,与本指南完全相同:http://spring.io/guides/gs/rest-service/ 除了我希望对象以xml而不是JSON的形式返回之外。 有人知道我怎么能做到吗?Spring有什么依赖项可以像XML一样轻松地做到这一点吗?或者,我是否需要使用封送器,然后以其他方式返回xml文件?