1

我正在使用 Web Api 并且有一个场景,客户端每隔n秒发送一次心跳通知。有一个心跳对象是在 POST 而不是 PUT 中发送的,因为在我看来,它们正在创建一个新的心跳而不是更新现有的心跳。

此外,客户端有一个要求,要求他们检索所有其他当前在线的客户端以及单个客户端拥有的未读消息的数量。在我看来,我有两个选择:

  1. 执行 POST,然后执行 GET,从纯 REST 的角度来看,这对我来说似乎更干净。我正在创建和检索,我认为 SOLID 原则更愿意相应地拆分它们。但是,这种方法意味着两次往返。
  2. 让 POST 返回一个对象,该对象包含与 GET 否则会完成的相同信息。这会将所有内容合并到一个请求中,但我担心这种方法会被认为是不明智的。这不是一个纯粹的 POST。

删除的选项 #2 如下所示:

public HeartbeatEcho Post(Heartbeat heartbeat)
    {
    }

HeartbeatEcho 是一个包含其他在线客户端的属性和未读消息数的类。

Web Api 当然支持选项#2,但仅仅因为我可以做某事并不意味着我应该这样做。选项#2 是可憎的、过早的优化还是实用主义?

4

2 回答 2

6

选项2根本不是可憎的。POST 请求创建一个新资源,但资源本身返回给调用者是很常见的。例如,如果您的资源是数据库中的项目(例如,Person),则 POST 请求将发送 INSERT 操作所需的成员(例如,姓名、年龄、地址),并且响应将包含 Person 对象,该对象在除了作为输入传递的参数之外,它还有一个标识符(数据库主键),可用于唯一标识对象。

请注意,对于 POST 请求仅返回新创建资源的 id 也是完全有效的,但这是您可以选择的,具体取决于客户端的要求。

public HttpResponseMessage Post(Person p)
{
    var id = InsertPersonInDBAndReturnId(p);
    p.Id = id;
    var result = this.Request.CreateResponse(HttpStatusCode.Created, p);
    result.Headers.Location = new Uri("the location for the newly created resource");
    return result;
}
于 2012-07-14T03:50:21.313 回答
3

无论哪种方式解决您的业务问题都会奏效。您是正确的 POST 新记录与 PUT 更新现有记录。

建议: 您可能要考虑的一件事是将 Redis 添加到您的堆栈中,并且应用程序可以非常快速地发布,然后您可以将 Pub/Sub 功能用于 echo 部分或 Blpop(阻塞直到记录匹配标准)。它超级快,可以帮助您扩展并为您尝试做的事情完美设计。

见:http ://redis.io/topics/pubsub/

见:http ://redis.io/commands/blpop

我已经将 Redis 用于类似的用途,但也使用了 RabbitMQ 和 RabbitMQ,我们添加了 socket.io 连接来实时“流式传输”心跳,而无需长时间轮询。

于 2012-07-14T03:46:28.283 回答