通过REST(RESTful)API进行批量收集操作


73

我想要有关设计REST API的一些建议,该API将允许客户端有效地向集合中添加/删除大量对象。

通过API,客户需要能够向集合中添加项目,从集合中删除项目以及操纵现有项目。在许多情况下,客户可能希望对该集合进行批量更新,例如添加1000个项目并删除500个不同的项目。感觉客户端应该能够在与服务器的单个事务中完成此任务,而不是需要1000个单独的POST请求和500个DELETE。

是否有人有关于实现此目标的最佳做法或惯例的信息?

我目前的想法是,应该能够PUT一个代表集合URI更改的对象,但这似乎与HTTP 1.1 RFC不一致,后者似乎建议在PUT请求中发送的数据应独立于数据包的解释。 URI中已经存在的数据。这意味着客户端将必须一次性发送对集合的新状态的完整描述,该描述可能远远大于更改,甚至超过客户端发出请求时所知道的范围。

显然,如果有必要,我很乐意偏离RFC,但如果存在这样的约定,则宁愿以常规方式进行操作。


您是使用API​​控制客户端还是需要支持现有的客户端产品?换句话说:您可以自由定义请求实体的语义吗?
mkoeller

Answers:


63

您可能想将变更任务本身视为一种资源。因此,您实际上是在放入单个对象,这是一个批量数据更新对象。也许它具有名称,所有者以及CSV,XML等大块文件,需要对其进行解析和执行。对于CSV,您可能还需要确定CSV数据中表示的对象类型。

列出作业,添加作业,查看作业状态,更新作业(可能是为了启动/停止作业),删除作业(如果正在运行则将其停止)等。这些操作可以轻松地映射到REST API设计中。

完成此操作后,您可以轻松添加批量数据更新程序可以处理的不同数据类型,甚至可以在同一任务中将它们混合在一起。换句话说,无需为要导入的每种类型的东西在整个应用程序中重复使用相同的API。

这也很容易使其适合于后台任务实现。在这种情况下,您可能希望向各个任务对象添加字段,以允许API客户端指定如何通知它们(完成后希望您获取或发送电子邮件的URL,等等)。 。


2
这需要作为答案进行检查!
HDave 2012年

2
好答案。如果要将操作应用于大量资源,并且要使用过滤条件选择它们,则可以将具有过滤条件的对象传递给变更任务。
Ameba Spugnosa 2013年

2
尽管避免“闲聊”的删除是合理的,但它又回到了RPC的思想中……也许可行的是获取集合,删除所有要删除的内容,然后放入集合(使用409响应状态检测竞争条件)并发修饰符)。如果对GET进行分页,则这样做的可行性降低了,在这种情况下,PATCH可能是正确的选择。
delitescere


2

您应该使用AtomPub。它是专门为通过HTTP管理集合而设计的。您选择的语言甚至可能会实现。


3
实际上,AtomPub仅定义将单个项目添加到集合中并删除它们。因此,我不会将其称为“专为管理馆藏而设计”。
朱利安·雷施克

2

至少对于POST而言,似乎您应该能够发布到列表URL,并使请求正文包含新资源列表而不是单个新资源。


1

据我了解,REST意味着代表状态转移,因此您应该将状态从客户端转移到服务器。

如果这意味着要来回传输大量数据,则可能需要更改表示形式。可以将collectionChange结构与一系列删除(按id)和添加(具有嵌入式完整xml表示形式)一起工作,并将其发布到处理接口URL。接口实现可以选择自己的服务器端删除和添加方法。

最纯净的版本可能是通过URL定义项目,并且该集合包含一系列URL。客户端更改后,可以对新集合进行PUT,然后对要添加的项目进行一系列PUT,如果要真正从服务器中删除项目而不是仅从列表中删除它们,则可以进行一系列删除。


0

您可以引入不需要收集整个状态的现有集合元素的元表示,因此在某些抽象代码中,更新可能如下所示:

{现有元素1-100}
{值为“ bar”,“ baz”的新元素foo}
{现有元素105}
{值为“ bar”,“ foo”的新元素foobar}
{现有元素110-200}

添加(和修改)元素是通过定义它们的值来完成的,删除元素是通过不提及它的新集合来完成的,而重新排序元素是通过指定新的顺序来完成的(如果已存储所有订单)。

这样,您可以轻松表示整个新集合,而不必重新传输整个内容。使用If-Unmodified-Since标头可确保您对内容的想法确实与服务器的想法相符(这样,您就不会意外删除根本不知道何时提交请求的元素)。


如果我正确理解了您提出的更新格式,则存在缺点,即不是幂等的,因为您以相对的方式(通过使用索引)引用了集合元素-如果PUT两次对服务器进行更新(可能是偶然的话),可能会导致集合损坏;例如元素编号 105第二次与第一次不同;不同的元素101-104将在第二次被删除。
stakx-不再贡献

0

最好的方法是:

Pass Only Id Array of Deletable Objects from Front End Application To Web API
    2. Then You have Two Options: 
       2.1 Web API Way : Find All Collections/Entities using Id arrays and Delete in API , but you need to take care of Dependant entities like Foreign Key Relational Table Data too
     2.2. Database Way : Pass Ids to your database side, find all records in Foreign Key Tables and Primary Key Tables and Delete in same order i.e. F-Key Table records then P-Key Table records
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.