我正在基于新的ASP.NET Web API创建Web API。我正在努力了解处理人们同时提交多个数据集的最佳方法。如果他们有100,000个请求,那么让他们一次提交1,000个就好了。
假设我的联系人控制器中有一个新的Contact方法:
public string Put(Contact _contact)
{
//add new _contact to repository
repository.Add(_contact);
//return success
}
允许用户“批量”提交新联系人的正确方法是什么?我在想:
public string BatchPut(IEnumerable<Contact> _contacts)
{
foreach (var contact in _contacts)
{
respository.Add(contact);
}
}
这是一个好习惯吗?这会解析一个带有JSON联系人数组的GET请求(假设它们格式正确)吗?
最后,有关如何最好地响应批量请求的任何提示?如果300中的4个失败怎么办?
万分感谢!
答案 0 :(得分:2)
当您输入集合时,您要么插入整个集合,要么替换现有集合,就像它是单个资源一样。它与GET,DELETE或POST非常相似。这是一个原子操作。使用是作为对PUT的单个调用的替代,联系人可能不是非常RESTfull(但这确实是开放的辩论)。
您可能需要查看HTTP pipelining并发送同一套接字的多个PutContact请求。对于每个请求,您可以返回该单个请求的标准HTTP状态。
我过去使用SOAP实现了批量更新,当系统负载时,我们遇到了许多无法预料的问题。如果你不注意,我怀疑你会遇到同样的问题。
因此,我的建议是HTTP pipelining。
<强>更新强>
我的建议是将批量创建联系人作为异步过程处理。假设“作业”与“批量创建”过程相同。所以服务可能如下所示:
public class JobService
{
// Post
public void Create(CreateJobRequest job)
{
// 1. Create job in the database with status "pending"
// 2. Save job details to disk (or S3)
// 3. Submit the job to MSMQ (or SQS)
// 4. For 20 seconds, poll the database to see if the job completed
// 5. If the job completed, return 201 with a URI to "Get" method below
// 6. If not, return 202 (aka the request was accepted for processing, but has not completed)
}
// Get
public Job Get(string id)
{
// 1. Fetch the job from the database
// 2. Return the job if it exists or 404
}
}
从队列中消耗内容的后台进程可以更新数据库,或者对服务执行PUT以将Job的状态更新为正在运行和已完成。
您需要其他服务来浏览刚刚处理的数据,解决错误等问题。
您的后台进程可能需要容忍验证错误。如果没有,或者如果您的服务进行了验证(假设您没有进行数据库调用等,无法保证响应时间),您可以返回一个类似CreateJobResponse的结构,其中包含足够的信息供客户端解决问题并重新提交请求。如果必须进行一些耗时的验证,请在后台进程中执行此操作,将作业标记为失败,并使用允许客户端修复错误并重新提交请求的信息更新作业。这假设客户端可以对作业失败的事实做一些事情。
如果Create方法将作业请求分解为许多较小的“作业”,则必须处理这样一个事实,即它可能不是原子的,并且会对监视作业是否成功完成提出许多挑战。
答案 1 :(得分:0)
PUT操作应该替换资源。通常,您针对单个资源执行此操作,但在针对集合执行此操作时,这意味着您将原始集合替换为传递的数据集。不确定你是否有意这样做,但我假设你只是更新集合的一个子集,在这种情况下,PATCH方法会更合适。
最后,有关如何最好地响应批量请求的任何提示?如果300中的4个失败怎么办?
这真的取决于你。只有一个响应,因此您可以发送200 OK或400 Bad Request并将详细信息放入正文中。