简体   繁体   English

如何编写删除 REST API 接受一长串要删除的项目?

[英]How to write delete REST API that accepts a long list of items to delete?

I'm writing RESTful APIs and am getting used to the recommended protocols for using HTTP verbs for different operations.我正在编写 RESTful API,并且习惯了使用 HTTP 动词进行不同操作的推荐协议。

However, I'm not sure how those protocols handle the case where you are deleting a potentially long list of items.但是,我不确定这些协议如何处理您删除可能很长的项目列表的情况。

It appears that, like GET, the DELETE verb has no body and so is limited to the length of a URL.看起来,像 GET 一样,DELETE 动词没有主体,因此仅限于 URL 的长度。 So how could you support accepting an arbitrarily long list of items to be deleted?那么你怎么能支持接受任意长的要删除的项目列表呢?

From the top....从一开始....

HTTP is our standard for self-descriptive messages, which is subject to the uniform interface constraint . HTTP是我们的自描述消息标准,受统一接口约束 That in turn means that everyone on the web understands HTTP requests the same way.这反过来意味着 web 上的每个人都以相同的方式理解 HTTP 请求。

In other words换句话说

DELETE /api/users/5b45eda8-067c-42c1-ae1b-e0f82ad736d6

has the same meaning as具有相同的含义

DELETE /www/home.html

In both cases, we're asking the server to enact a change to its resource model .在这两种情况下,我们都要求服务器对其资源 model进行更改。

Because everyone understands these requests the same way, we can create general purpose components (ex: caches) that understand the meaning of messages in the transfer of documents over a network domain and can therefore do intelligent things (like invalidating previously cached responses).因为每个人都以相同的方式理解这些请求,所以我们可以创建通用组件(例如:缓存),这些组件可以理解在网络域上传输文档时消息的含义,因此可以做一些智能的事情(比如使以前缓存的响应无效)。

And we can do this even though the general purpose components know nothing about the semantics of the resource, and nothing about the underlying domain model hidden behind the resource.即使通用组件对资源的语义一无所知,对隐藏在资源后面的底层域 model 一无所知,我们也可以做到这一点。

DELETE, in HTTP, always specifies a single target URI; DELETE,在 HTTP 中,始终指定单个目标 URI; "bulk delete" is not an option here. “批量删除”在这里不是一个选项。

(I haven't found any registered HTTP methods that describe a bulk delete to general purpose components. It's possible that one of the WebDAV methods could express those semantics, but the WebDAV standard also has a lot of other baggage - I wouldn't try repurposing those methods for a "normal" API.) (我还没有找到任何已注册的 HTTP 方法来描述对通用组件的批量删除。可能其中一种 WebDAV 方法可以表达这些语义,但 WebDAV 标准也有很多其他包袱 - 我不会尝试将这些方法重新用于“正常”API。)

So if you are trying to DELETE three resources in your API, then you are going to need three requests to do it -- just like you would if you were trying to DELETE three pages on your web site.因此,如果您尝试删除 API 中的三个资源,那么您将需要三个请求来执行此操作 - 就像您尝试删除 web 站点上的三个页面一样。


That said, if deleting a bunch of resources on your web site using a single HTTP request is more important than letting general purpose components understand what is going on: you have the option of using POST也就是说,如果使用单个 HTTP 请求删除 web 站点上的一堆资源比让通用组件了解正在发生的事情更重要:您可以选择使用 POST

POST serves many useful purposes in HTTP, including the general purpose of “this action isn't worth standardizing.” POST 在 HTTP 中有许多有用的用途,包括“此操作不值得标准化”的一般用途。 -- Fielding, 2009 ——菲尔丁,2009

General purpose components will understand that the resource identified by the target URI is changing in some way, but it won't understand what is happening in the payload.通用组件将了解目标 URI 标识的资源正在以某种方式发生变化,但它不会了解有效负载中发生的情况。

In theory, you could standardize a payload that means "we're deleting all of these resources", and then general purpose components could be implemented to recognize that standard.理论上,您可以标准化表示“我们正在删除所有这些资源”的有效负载,然后可以实现通用组件来识别该标准。 In practice, good luck.在实践中,祝你好运。


Now, if instead what you want is a bulk delete of entities in your domain model , you have some options available.现在,如果您想要的是批量删除域中的实体 model ,那么您有一些可用的选项。

On the web, we would normally use something like a form - perhaps with a check box for each entity.在 web 上,我们通常会使用类似表格的东西——也许每个实体都有一个复选框。 You select the entities that you want to delete, submit the form, and the HTTP request handler parses the message, then forwards the information to your domain model.您 select 要删除的实体,提交表单,然后 HTTP 请求处理程序解析消息,然后将信息转发到您的域 model。

You could achieve something similar with a remote authoring idiom - here's a resource whose representation is a list of entities.您可以使用远程创作习语来实现类似的目标 - 这是一个资源,其表示形式是实体列表。 You PUT to the server a copy of that document with entities removed, and then on the server you make changes to the domain model to match.您将删除实体的该文档的副本放入服务器,然后在服务器上更改域 model 以匹配。

It's a very declarative approach: "change the domain model so that the representation of the resource will look like this".这是一种非常声明性的方法:“更改域 model 以便资源的表示看起来像这样”。

This is analogous to how you would use HTTP to fix a spelling error in a web page: send a PUT request with the new HTML (including the spelling correction) in the request body.这类似于您如何使用 HTTP 修复 web 页面中的拼写错误:使用新的 HTML 发送 PUT 请求(包括请求正文中的拼写更正)。

PATCH is very much the same idea: we describe changes to the representation of the resource, and the server passes that information to the domain model. PATCH 的想法非常相似:我们描述对资源表示的更改,然后服务器将该信息传递给域 model。 The difference here being that instead of sending the entire representation, we just send a patch document that describes the correction.这里的不同之处在于,我们不是发送整个表示,而是发送一个描述更正的补丁文档。

If you want an imperative approach - just use POST如果您想要一种命令式方法 - 只需使用 POST

POST /Bob
Content-Type: text/plain

Bob,
Please delete domain entities 1, 2, 5, 7

General purpose components won't understand how you are trying to modify the target resource, but they'll at least know that much.通用组件不会理解您尝试修改目标资源的方式,但它们至少会知道这么多。


Where things get messy is when there are lots of resources whose representation depends on the same resources.当有很多资源的表示依赖于相同的资源时,事情就会变得混乱。 The standards don't offer us much in the way of affordances to announce "here are all the resources that have changed".这些标准并没有为我们提供太多的可供性方式来宣布“这里是所有已更改的资源”。

Cache invalidation is one of the two hard problems.缓存失效是两个难题之一。 HTTP has some affordances that work in the simple cases, but trade offs become necessary when things get more complicated. HTTP 有一些适用于简单情况的可供性,但当事情变得更复杂时,权衡变得必要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM