REST:更新多个记录

12

我需要使用单个HTTP请求更新多个记录。例如,选择一系列电子邮件并将它们标记为“未读”。最佳(Restful)方法是什么?

我目前采用的方法是使用子资源操作

PUT http://example.com/api/emails/mark-as-unread

(在正文中)

{ids:[1,2,3....]}


如果您不会在其他地方使用“全部更新”功能,我认为这是一个不错的选择,但如果您要使用它,请创建另一条按ID更新的路由,这就是我会做的方式。 - Mr Br
你的意思是像 http://example.com/api/emails/bulk-update 这样,然后传递一个对象数组吗? - Tharaka
是的,就像那样,选择最能描述你的函数的路线。 - Mr Br
3个回答

8
我阅读了这个网站 - http://restful-api-design.readthedocs.io/en/latest/methods.html#actions ,它建议使用“actions”子集。例如:

POST http://example.com/api/emails/actions

(在正文中)

{"type":"mark-as-unread", "ids":[1,2,3....]}

从参考网页中摘录的引用:

有时需要在API中公开无法 RESTful 执行的操作。其中一种操作的示例是,您想要为资源引入状态更改,但存在多种方法可以实现相同的最终状态,... 这种非 RESTful 操作的解决方案之一是在资源上使用“actions”子集。操作基本上是发送到资源的类似于RPC的消息,以执行某个操作。 “Actions” 子集可以被视为命令队列,新动作可以通过 POST 添加,然后由 API 执行。...

值得注意的是,只有在有充分理由不能将操作映射到标准 RESTful 方法之一时才应该使用 actions。


6
创建一个算法终点,例如:
http://example.com/api/emails/mark-unread

bulk-update是一个算法名称,它是一个名词。在REST中,它成为终端点名称,id列表是该算法的参数。通常人们将它们作为URL查询参数发送到POST调用中。

http://example.com/api/emails/mark-unread?ids=1,2,3,4

这非常安全,因为POST是不幂等的,并且您不需要担心任何副作用。如果您的批量更新携带了这些对象的整个状态,则可以选择 PUT

http://example.com/api/emails/bulk-change-state

那么您需要将实际状态放入http调用的正文中。 我更喜欢一堆简单的算法,比如mark-unread?ids=1,2,3,4,而不是一个庞大的PUT,因为它有助于调试,在日志中透明等。


5
根据我从他人阅读的RESTful的内容来看,其概念是所有URI代表资源(即名词),在任何URI的部分中都不应该有动词。因此,引入“标记未读”似乎不太符合RESTful的方式。 - Johnny Wong
@JohnnyWong 虽然看起来像是一个动词,但你可以将“mark-unread”视为算法名称以避免混淆。 - Igor Katkov
@Johnny Wong,那么对于像在分页资源上进行“全部标记为已读”这样的操作,您会如何处理? - Ledorub
@Ledorub,你的问题取决于你想要参数如何表示那一页的邮件-是通过列出所有ID还是其他方式。我没有固定的建议。 - Johnny Wong

2

将模型数组作为参数传递给操作方法有点复杂。最简单的方法是从客户端生成一个 JSON 字符串,并将其 POST 到服务器(即您的操作方法)。您可以采用以下方法:

假设您的电子邮件模型如下所示:

public class Email
{
    public int EmailID {get; set;}
    public int StatusID {get; set;}
    // more properties
}

因此,您的操作方法将采取以下形式:

public bool UpdateAll(string EmailsJson)
{
    Email[] emails = JsonConvert.DeserializeObject<Emails[]>(EmailsJson);
    foreach(Email eml in emails)
    {
        //do update logic
    }
}

使用Json.NET来辅助序列化。
在客户端,您可以按照以下方式编写Ajax调用:
$.ajax({
    url: 'api/emailsvc/updateall',
    method: 'post',
    data: {
        EmailsJson: JSON.stringify([{
            ID: 1,
            StatusID:2,
            //...more json object properties.
            },
            // more json objects
            ])
        },
    success:function(result){
        if(result)
            alert('updated successfully');
    });

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