通过在RESTful API中POST集合来创建项目

时间:2014-10-22 19:44:57

标签: api rest

我试图通过设计API来学习REST原则,并尽可能地遵循REST的原则。 REST API中一种非常常见的做法是通过POST创建资源,如下所示:

{
    "address_1": "123 Main St.",
    "city": "Anywhere",
    "some": "more stuff"
}

要创建地址,您只需POST即可:/api/customers/ABC123/addresses

......然后回复一下:

201 Created Location: /api/customers/ABC123/addresses/XYZ789

我认为这很清楚。但是,当您想要一次创建多个地址时,情况如何:

[
   {
      "address_1":"123 Main St.",
      "city":"Anywhere",
      "some":"more stuff"
   },
   {
      "address_1":"456 State St.",
      "city":"Somewhere",
      "some":"more stuff"
   }
]   

在这种情况下,我仍会发布到/api/customers/ABC123/addresses,但是,我无法将位置返回到资源,因为已创建了多个位置。但是,我想可以返回集合的位置,例如:

201 Created Location: /api/customers/ABC123/addresses

但是,根据我自己使用API​​的经验,我似乎只遇到了一个项目的创建(如我的第一个例子),而不是在一个POST中创建多个项目(如我的第二个例子)。所以,我的问题是:

第二个例子是不好的做法吗?如果是这样,为什么?似乎允许在单个POST中创建多个项目将很方便并减少喋喋不休。

如果第二个示例 是一种不好的做法,是否适合按照我在第二个示例中显示的那样返回位置?

感谢您的任何建议。

2 个答案:

答案 0 :(得分:1)

如果您在上面描述,您实质上是通过添加其他地址来修改客户资源。您还添加了一个约束,因为您希望能够一次添加多个地址。

让我们接受这个要求。

那你做什么?与大多数软件问题一样。不一定是最好的解决方案。这里有几个选项...

您可以更新整个客户,例如PUT /api/customers/ABC123。也许,客户端首先GET是客户,然后将新的地址添加到地址属性,最后将其返回给服务器。该操作返回200(无需返回201的位置,因为您刚刚调用了要返回的位置)。另外,请记住,使用REST时,PUT必须是幂等的,因此反复调用它应始终产生相同的结果。

同样地,(并且有点奇怪)如果客户资源由于某种原因超大,您可以使用整个新列表在PUT执行/api/customers/ABC123/addresses操作并再次返回{{1} (再次,不需要返回您刚刚调用它的位置)。

现在假设事情变得非常毛茸茸而且客户200跟着PUT就行不通(无论出于何种疯狂的原因)。您将获得一个要求,即您必须通过仅提供新地址来提供修改地址列表的方法。在这里,GET并不合适,因为它不是幂等的。 PUT但是没有幂等性的要求,因此,POST是有意义的。但是你在Location标题中返回了什么位置?随机选择一些项目没有意义。返回所有客户地址的位置也没有意义。好吧,幸运的是POST可以提供一个。在这种情况下,只需返回状态POST。尽管如此,这' 闻起来'。它并不觉得RESTful。这是你必须退后一步意识到的,嘿,REST很棒!但是,它不是一颗银弹。有时候事情并不完美。在这样的情况下,你最好找到一种RESTful方式,但有时候,它并不存在。在这种情况下,您可能需要为该功能提供Web服务样式端点。

  • 请参阅有关RESTful设计原则的blog帖子

答案 1 :(得分:0)

响应是您想要提供的任何内容。

您的回复可能是一个阵列或地点集合,或简单的成功"或者"失败"字符串,甚至是你希望通过某些javascript放入div中的html表。您正在构建API,以便您决定响应应该是什么样子。

有许多工具可以自动将功能转换为REST端点,因此您可以考虑使用其中一种。一个好处是你可以返回一些东西,也许是一个字符串数组,它会自动将它转换为xml或json或yaml或任何类型的请求。