多个删除的 REST 架构?

7

我发出了一个删除请求到服务器,就像这样:

@RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE)

针对单个用户进行删除操作很简单,但是如果有多个用户需要删除怎么办?我希望遵循REST架构,但不想通过发送多个删除请求的方式来实现。有没有其他的解决方式?

PS:这种方式可行吗:

@RequestMapping(value = "/user", method = RequestMethod.DELETE, headers = "Accept=application/json")
    public void deleteUser(HttpServletResponse response, @RequestBody String users) throws IOException {
        ...
}

你是不是想说 RequestMethod.DELETE - Tomasz Nurkiewicz
1
@kamaci:通常DELETE没有正文,因此您无法将用户ID与其一起发送。 DELETE通常会删除整个资源(以及所有子资源)。我写了一个答案,使用POST而不是DELETE,但类似于您的编辑。 - ZeissS
4个回答

6

由于REST是面向资源的架构,因此请尝试设计更高级别的域对象来表示“多个用户”资源,然后对该对象执行删除操作。

也许可以这样做。

@RequestMapping(value = "/users/expired", method = RequestMethod.Delete)

伟大的书籍“Restful Web Services Cookbook”由Subbu Allamaraju, O'Reilly出版社,讲述了以下主题:

  • 第11.10章,如何批量处理相似的资源;
  • 第11.11章,如何触发批处理操作;
  • 第11.12章,何时使用POST合并多个请求;
  • 第11.13章,如何支持批处理请求。

它不必是一个域对象,只需要是表示对象集合的附加资源。 - Darrel Miller
是的,这是最好的选择。另一个选项是HTTP管线化,但它还没有被广泛实现。附言:为了您的接受率,请采纳一个答案 :-) - Jan Algermissen
你建议将用户发送到一个主体吗? - kamaci
是的,但URI、请求体格式和响应代码应该仔细设计。因此,在开始编码之前,如果可能的话,请阅读Sbbu Allamaraju的《RESTful Web Services Cookbook》(O'Reilly出版社):第11.12页,何时使用POST合并多个请求;以及第11.13页,如何支持批量请求。 - swanliu

2
我了解REST,知道使用POST来实现DELETE是违反REST规范的。但我无法确切地说明这个规则的好处所在。
我猜测这可能与API工具的可行性有关(例如开发工具不需要根据动词定义的给定状态进行配置就能够理解特定API方法的具体含义),或者与在部分成功删除的情况下无法返回细粒度错误有关,但这只是猜测,并不是本问题的核心。
Swanliu的回答提到将表示分组结构的URL作为删除的目标,但给出的示例“/users/expired”表明这是一个固定(可能是系统定义的)分组。更多面向用户的任意集合情况仍需要在某个时刻枚举才能实现。
对于大小为N的组,发出N个DELETE请求既复杂又缺乏原子性,但REST DELETE只能针对单个资源。
我认为Swanliu的回答暗示的最佳实践可能是定义一个POST操作,能够创建一个新的上级容器资源,以便删除对象。POST可以返回一个主体,因此该系统可以为这个非域分组资源创建一个唯一标识符,并将其返回给客户端,客户端可以再次发出请求来删除它。POST创建的资源生命周期短暂但有目的——它的消失会级联到预期的批量删除操作的域对象。
> POST /users/bulktarget/create
> uid=3474&uid=8424&uid=2715&uid=1842&uid=90210&uid=227&uid=66&uid=54&uid=8
> ...
< ...
< 200 OK
< ae8f2b00e

> DELETE /users/bulktarget/ae8f2b00e
> ...
< ...
< 200 OK

虽然两次网络交换不如一次好,但是考虑到小批量删除包含两个对象,如果不进行任何处理就需要进行两个DELETE操作,因此这似乎是一个公平的权衡 - 可以将其视为您免费获得了第二个对象之后的所有对象。


1

我对REST的理解是这正是你必须做的。如果有其他选择,我也很想知道 :)

如果您不想发送多个删除请求,则必须设计更粗糙的API。(这就是为什么大多数API都是RESTful而不是REST的原因)

顺便说一句,我认为您需要使用RequestMethod.DELETE?


0
据我所知,基本的REST是用于处理单个资源的。我会选择向/user/资源发送POST请求,并使用特殊的deleteUsers请求体来包含要删除的ID。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接