通过Web Api在POST中返回对象是不好的做法?

时间:2012-07-14 03:34:28

标签: rest asp.net-web-api solid-principles

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

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

  1. 执行POST后跟GET,从纯粹的REST角度来看,这似乎更清晰。我正在进行创建和检索,我认为SOLID原则更愿意相应地拆分它们。但是,这种方法意味着两次往返。
  2. 让POST返回一个对象,该对象包含与GET原本相同的信息。这将所有内容整合到一个请求中,但我担心这种方法会被认为是不明智的。这不是一个纯粹的POST。
  3. 选项#2被删除看起来像这样:

    public HeartbeatEcho Post(Heartbeat heartbeat)
        {
        }
    

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

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

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:3)

无论哪种方式解决您的业务问题都可行。对于新记录和PUT更新现有记录,你是正确的POST。

<强> SUGGESTION: 您可能需要考虑的一件事是将Redis添加到您的堆栈中,并且应用程序可以非常快地发布,然后您可以使用发布/子功能进行回声部分或Blpop(阻塞直到记录匹配条件)。它速度非常快,可以帮助您扩展并完美地设计您想要做的事情。

请参阅:http://redis.io/topics/pubsub/

请参阅:http://redis.io/commands/blpop

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