我需要使用单个HTTP请求更新多个记录。一个例子是选择电子邮件列表并将其标记为“未读”。实现这一目标的最佳(Restful)方式是什么?
我现在的做法是使用子资源操作
PUT http://example.com/api/emails/mark-as-unread
(在体内)
{ids:[1,2,3....]}
答案 0 :(得分:5)
我读了这个网站 - http://restful-api-design.readthedocs.io/en/latest/methods.html#actions - 它建议使用“动作”子集合。 e.g。
POST http://example.com/api/emails/actions
(在体内)
{“type”:“mark-as-unread”,“ids”:[1,2,3 ....]}
有时,需要在API中公开本质上不是RESTful的操作。这种操作的一个例子是你想要为资源引入状态变化,但是有多种方法可以实现相同的最终状态,...一个很好的例子是“断电”之间的区别“以及虚拟机的”关闭“。
作为此类非RESTful操作的解决方案,可以在资源上使用“actions”子集合。对于执行特定操作的资源,操作基本上是类似RPC的消息。 “actions”子集合可以看作是一个命令队列,新的动作可以被POST,然后由API执行。 ...
应该注意的是,当一个操作无法映射到标准RESTful方法之一的充分理由时,操作应仅用作例外。 ...
答案 1 :(得分:4)
创建算法端点,如
http://example.com/api/emails/mark-unread
bulk-update
是算法名称,名词。它将成为REST中的端点名称,id列表是此算法的参数。通常人们会在POST
调用中将其作为URL查询参数发送,如
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
因为它有助于调试,透明的日志等
答案 2 :(得分:1)
将一组模型作为参数添加到动作方法中有点复杂。最简单的方法是从客户端形成一个json字符串,然后将所有这些字符串发送到服务器(到您的操作mehtod)。您可以采用以下方法
说你的电子邮件模型是这样的:
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');
});