RESTful方式在一个请求中创建多个项目

116 rest post

我正在开发一个小型客户端服务器程序来收集订单.我想以"REST(ful)方式"这样做.

我想做的是:

收集所有订单行(产品和数量)并将完整订单发送到服务器

目前我看到两个选项:

  1. 将每个订单行发送到服务器:POST qty和product_id

我实际上不想这样做,因为我想限制对服务器的请求数量,所以选项2:

  1. 收集所有订单行并立即将它们发送到服务器.

我该如何实施选项2?我的一些想法是:将所有订单行换行到JSON对象中并将其发送到服务器或使用数组发布订单行.

实施选项2是一个好主意还是一个好习惯,如果是,我该怎么办呢.

什么是好习惯?

mig*_*ain 65

我认为另一种正确的方法是创建另一个代表您的资源集合的资源.例如,假设我们有一个端点/api/sheep/{id},我们可以POST /api/sheep来创建一个绵羊资源.

现在,如果我们想要支持批量创建,我们应该考虑一个新的flock资源/api/flock(或者/api/<your-resource>-collection如果你缺少一个更有意义的名字).请记住,资源不需要映射到您的数据库或应用程序模型.这是一个普遍的误解.

资源是更高级别的表示,与您的数据无关.在资源上操作可能会产生严重的副作用,例如向用户发出警报,更新其他相关数据,启动长期存在的进程等.例如,我们可以将文件系统甚至unix ps命令映射为REST API.

我认为可以安全地假设操作资源也可能意味着创建其他几个实体作为副作用.

  • 我喜欢你用绵羊和羊群命名的api端点!在某种程度上,它几乎有一个圣经参考:*“我还有其他羊,不是这个圈子里的;我也必须把它们带来,他们会听到我的声音;他们将成为一个牧羊人的羊群。” * 约翰福音 10:16。 (3认同)
  • 有趣的是,当您想要创建单个资源时,人们建议在 URL 中使用(集合的)复数形式,如下所示:向 /api/books 发送 POST 来创建一本书。但是,当您想要创建 100 本书(在单个请求中作为 json)时,您会将 100 本书的集合发布到哪个 URL?这就是不安开始的地方。 (2认同)

Lio*_*orH 44

虽然批量操作(例如批量创建)在许多系统中都是必不可少的,但RESTful架构风格并没有正式解决这些问题.

我发现按照你的建议发布一个集合基本上可行,但是当你需要报告失败以响应这样的请求时会出现问题.当因不同原因发生多次故障或服务器不支持事务时,此类问题会更​​严重.我的建议是,如果没有性能问题,例如当服务提供商在LAN(而不是WAN)上或数据相对较小时,向服务器发送100个POST请求是值得的.保持简单,从单独的请求开始,如果遇到性能问题,请尝试优化.

  • 这是无稽之谈.问题是关于发送许多项目的订单,正如许多人所说,你可以只在一个POST请求的实体中.服务器如何处理这完全是另一回事.在这种情况下,我认为创建订单没有问题,为该订单填充了您可以填写的内容,并且还填充了无法执行的详细信息.这样,用户就可以看到他们的订单了,看到除了N个项目之外的所有项目都被添加到订单中,但是有些商品缺货,或者系统不知道该怎么做.另一个更简单但用户友好的选择是拒绝一切 (5认同)
  • @dlamblin是的,我应该做很多事情......我会在某个阶段得到它... (3认同)
  • 在批处理的情况下,您是否找到了自己的错误解决方案?在移动连接上发送100个帖子请求以显示页面接缝,就像一个坏主意. (2认同)
  • @thecoshman在3.25年间发生了很多变化.你应该对这个问题发表一个完全公开的答案. (2认同)

rwi*_*zel 10

Facebook解释了如何执行此操作:https://developers.facebook.com/docs/graph-api/making-multiple-requests

简单的批量请求

批处理API接收表示为JSON数组的逻辑HTTP请求数组 - 每个请求都有一个方法(对应于HTTP方法GET/PUT/POST/DELETE等),relative_url(graph.facebook之后的URL部分). com),可选的头数组(对应于HTTP头)和一个可选的主体(用于POST和PUT请求).Batch API返回表示为JSON数组的逻辑HTTP响应数组 - 每个响应都有一个状态代码,一个可选的头数组和一个可选的主体(它是一个JSON编码的字符串).

  • 这确实是Facebook的方式,不一定是OP要求的RESTful (4认同)
  • 我认为 Batch API(来自 Google、Facebook 等 - @PuneetArora)在将多个不相关的请求分组在一起时更有用。创建一个创建一个项目的请求,然后将所有这些请求分组在一起以发送一组项目是“疯狂的”(爱因斯坦)。只需创建一个传递项目集合的请求即可。 (3认同)
  • 这是非常有趣的链接,建议的解决方案对我来说似乎有用。无论如何,在 StackOverflow 上,首选答案是在答案正文中解释解决方案的概念,因为链接可能会更改或消失。 (2认同)

Mil*_*ota 8

你的想法似乎对我有用.实施是您的偏好问题.您可以使用JSON或仅使用参数("order_lines []"数组)并执行此操作

POST /orders
Run Code Online (Sandbox Code Playgroud)

由于您要在单个操作(顺序及其行)中一次创建更多资源,因此只有在所有这些资源都通过验证时才能验证它们中的每一个并保存它们,即.你应该在交易中做到这一点.


zak*_*rya 6

我想最好在单个连接中发送单独的请求.当然,您的Web服务器应该支持它


Eri*_*ler 5

我最近一直在努力解决这个问题,这就是我正在努力的方向.

如果添加多个资源的POST成功,则返回200 OK(我考虑的是201,但用户最终没有登陆已创建的资源)以及显示已添加的所有资源的页面 - 只有或可编辑的时尚.例如,用户能够使用仅包括单个文件输入的表单来选择多个图像并将其POST到图库.如果POST请求完全成功,则向用户呈现用于创建的每个图像资源表示的一组表单,其允许它们指定关于每个(名称,描述等)的更多细节.

如果无法创建一个或多个资源,POST处理程序将中止所有处理并将每个单独的错误消息附加到数组.然后,返回419冲突,并将用户路由到419冲突错误页面,该页面显示错误数组的内容,以及返回已提交表单的方式.


Che*_*ery -5

您不想发送 100 个订单行的 HTTP 标头。您不想生成不必要的请求。

将一个 JSON 对象中的整个订单发送到服务器,发送到:server/order 或 server/order/new。返回指向:server/order/order_id 的内容

还可以考虑使用CREATE PUT 而不是 POST

  • 您到底为什么要使用 PUT 来创建内容?这正是 HTTP POST 方法的用途。 (27认同)
  • 当您希望客户端指定资源的 URI(如 webdav 中)时,您可以使用 PUT 来创建资源。我不同意发帖者对 PUT 的使用,但它在创建资源方面确实有一席之地,尽管这个地方的范围可能有限。 (9认同)
  • 注意:POST 实体应导致该实体成为请求中寻址的资源的从属实体,并且不是幂等的。PUT 替换地址处的实体并且是幂等的。幂等性(这个词?)是消费者的一个重要期望。 (2认同)