如何构建删除需要很长时间的删除端点。
在我的应用程序中,我存储了一堆id并具有前缀批处理端点。例如:GET /prefix/{prefix}
会返回与{prefix}
匹配的所有ID。我想实现类似的DELETE
端点。现在,我完成了Response
成功或失败。
但是,删除可能需要很长时间,并且带有客户端的套接字超时会使删除处于损坏或不完整状态。
我想避免这种情况只是在实际执行删除之前返回一个响应。但我很好奇设计这个的正确方法是什么。 (即返回应该是什么?这是一个好的模型吗?等等)我们可以调用端点"尝试删除"而不是实际的删除,因为无法保证它会成功,如果失败则无法保证。
要求:
DELETE xyz
然后GET xyz
,则第二次请求返回尚未删除的对象。唯一的保证是,DELETE
完成后,在资源上执行GET
会抛出错误。(FWIW I' m使用java和jersey,但这不重要)
答案 0 :(得分:1)
如何构建删除需要很长时间的删除端点。
我希望你能以类似于任何其他需要很长时间的请求来处理它:202 Accepted
202(已接受)状态代码表示该请求已被接受处理,但处理尚未完成。
通过此响应发送的表示应该描述请求的当前状态,并指向(或嵌入)状态监视器,该状态监视器可以向用户提供对请求何时将被满足的估计。
如果您将删除操作视为正在运行的任务,并且该任务记录其进度,那么任务#X"的日志将被记录下来。资源是告诉客户如何发展的东西。
在这种情况下,在我的应用程序中,我存储了一堆id并具有前缀批处理端点。例如:GET / prefix / {prefix}返回匹配{prefix}的所有ID。我想实现类似的DELETE端点。
DELETE可能不适合使用。
DELETE方法请求源服务器删除目标资源与其当前功能之间的关联。实际上,此方法类似于UNIX中的rm命令:它表示对源服务器的URI映射执行删除操作,而不是期望删除先前关联的信息。
......相对较少的资源允许DELETE方法 - 它的主要用途是远程创作环境,用户对其效果有一些指导。
在语义上,这并不是一个很好的匹配,因为"将一个任务放在队列中,这些任务在逻辑删除了一堆实体"。
同样的想法,使用不同的拼写:请求
DELETE /prefix/xyzzy ...
表示"删除检索ids-with-prefix-xyzzy"的集合的功能,而不是"使ids-with-prefix-xyzzy的集合为空#34 ;
请记住,REST API的目的是让您的域看起来像Web上的其他内容;它是一个适配器(在Gang of Four意义上),从外部看起来像一个网站,但在内部非常熟悉您自己的服务。
菲尔丁在他的论文中写道REST通过将消息约束为自描述来启用中间处理:交互在请求之间是无状态的,标准方法和媒体类型用于指示语义和交换信息,响应明确指示可缓存性 - Section 5.3.1
在REST中,中间组件可以主动转换消息内容,因为消息是自描述的,并且中间人可以看到它们的语义 - Section 5.1.6
现在,说实话,REST警察太忙于抱怨你没有使用超媒体,没有其他人关心。任何人都不会尝试将API与通用远程创作客户端一起使用,并且即使您使用HTTP DELETE语义,缓存失效也是two hard problems之一。所以你很可能会逃脱它。
但是,修改一组域实体的REST API通常看起来像(短期)资源的 creation ,它描述了应该修改哪些实体。这是关于如何使用Web浏览器和HTML实现相同的结果:您将获取此前缀资源,并伴随ID的表示将是一个链接说"您要删除这些吗?单击此处",并获取该链接将加载表单,描述要修改的ID。表单将具有POST操作(向中间组件宣布这不是safe operation)。提交表单会将消息附加到队列,并像以前一样返回到进度表的链接。
答案 1 :(得分:0)
以下是我的意见,帮助它会有所帮助:)
由于HTTP协议在RFC standards中使用DELETE请求方法具有DELETE是一个好主意。但是,http有其局限性,它无法从服务器端采取操作,因此获取响应的唯一方法是从客户端定期检查或采取响应。
如果我是你,我会这样做。
大多数情况下该方法都可以。例如,如果两个客户端发送相同的删除操作,则两个操作之间不会发生冲突,但实际上会删除文件。
祝你好运