给定具有2个端点的REST API:
http://example.com/api/send?id=someId
客户端:
对此端点的调用是在代码中异步完成的。
服务器端:
收到请求后,会启动一些异步任务。该 然后服务器使用。等待那些异步任务的结果
await
个关键字。最后它返回结果。
http://example.com/api/sendAsync?id=someId&callbackUrl=http://something.com/done
客户端:
对此端点的调用是在代码中异步完成的。
服务器端:
收到请求后,会启动一些异步任务。服务器立即返回带有Id的结果以标识操作。只要结果可用,服务器就会使用结果和Id来调用callbackUrl。
为什么我需要第二种方法?
对我而言,第一种方法似乎同样出色。服务器使用await
关键字等待结果的事实使其成为非阻塞,因为关键字之后的所有内容都被注册为延续。客户端也是非阻塞的,因为它是异步Web请求。
我确实意识到第二种方法可能很有用,如果它是非常长的接收请求(+ 5分钟)。 - 但是,我无法帮助感觉我错过了什么。
答案 0 :(得分:2)
嗯,第一种方法适用于small(er) operations
,不需要在服务器端扩展。一个非常粗略的例子是这样的:
public Response SomeApiMethod(int a, int b)
{
return a + b;
}
这显然是你不能很好地扩展的东西,也是我将在你的第一种方法中提出的一个非常基本的操作。
现在,另一方面,如果你提供一些功能,需要在像巨大的数据库这样的东西上做一些really heavy lifting
,这可能会花费很长时间,那么你最好使用Callback approach
。复杂的操作往往比更简单的操作引起更多的错误,这些操作可以在服务器上以不同的方式处理。就像在作为回调过程一部分的事务中出现问题时,服务器可以简单地重新启动整个过程并仍然通知用户结果。
我想提一下你的第二种方法:
我假设你会使用ASP.NET
作为你的API,而且我目前还没有ASP.NET专家,但我很确定你不能只触发长时间运行Task
在已经返回响应的请求中,因为他们迟早会得到recycled
。
但是,您可以使用某种MessageQueue
(例如MSMQ,RabbitMQ ...)来接收有关您的任务的消息,然后可以通过灵活的客户数量。如果你需要扩展你的API以处理更多的用户,那么你只需要抛出更多的客户端来监听你的队列的新消息,你就基本完成了。
答案 1 :(得分:1)
我可以看到更多的用法:
1)非.net客户端可以轻松使用第二种方法
2)您希望处理不同网址的回调(支付系统API中的常见做法)