【问题标题】:Create single and multiple resources using restful HTTP使用 RESTful HTTP 创建单个和多个资源
【发布时间】:2012-06-22 17:13:41
【问题描述】:

在我的 API 服务器中,我定义了这条路由:

POST /categories

要创建一个类别:

POST /categories {"name": "Books"}

我想如果你想创建多个类别,那么你可以这样做:

POST /categories [{"name": "Books"}, {"name": "Games"}]

我只是想确认这对于 Restful HTTP API 来说是一个很好的做法。

或者应该有一个

POST /bulk

允许他们一次执行任何操作(创建、读取、更新和删除)?

【问题讨论】:

  • 是什么让你不能多次调用它?
  • 没什么 .. 但如果你想创建 1000 个资源,我怀疑你是否想进行 1000 次往返而不是 1 次。更少的时间、更少的金钱、更少的代码。

标签: web-services http rest web


【解决方案1】:

在真正的 REST 中,您可能应该在多个单独的调用中发布它。原因是每一个都会产生一个新的表示。否则,您将如何期望得到回报。

每个帖子都应返回结果资源位置:

POST -> New Resource Location
POST -> New Resource Location
...

但是,如果您需要批量,请创建批量。尽可能教条,但如果不是,实用主义就能完成工作。如果你太执着于教条主义,那么你什么也做不了。

Here is a similar question

Here is one that suggests HTTP Pipelining to make this more efficient

【讨论】:

  • +1 表示“实用主义可以完成工作”。我也在创建一个 API,并且必须创建数千个资源,我认为批量创建胜过每个资源一个 POST。
  • 另外 +1 表示“如果你太沉迷于教条主义,那么你将永远无法完成任何事情。” - 不能再同意了。
【解决方案2】:

进行 POST 到激活的批量操作并没有什么特别的问题(它将是非幂等的,因此 POST 是正确的动词),但有一些警告:

  • 您正在制作多个资源,因此您需要使用多个 URL 进行响应。这意味着您不能使用重定向模式:您必须以某种形式发回 URL 列表。

  • 您遇到的问题是批量操作通常不太容易被发现。可发现性是 RESTfulness 最重要的事情之一,因为这意味着有人可以在没有服务器作者大量帮助的情况下找到如何编写客户端。

  • 在进行批量操作时处理部分故障仍然存在问题。这也是任何其他范例的问题(我看到人们在使用 SOAP 扩展时为此纠结不已)所以这并不奇怪,但除非你能保证所有创作将起作用,您将不得不弄清楚当您制作一种资源而未能制作第二种资源时会发生什么。 (另外,如果批量请求需要完成第三个请求,您会继续尝试吗?)

最简单的方法就是支持一个请求创建一个;这是一个更容易正确的模式,并且更容易全面理解。

【讨论】:

  • 当您需要批量处理时,基本上是 ddos​​ 系统?
【解决方案3】:

使用 POST 一次创建多个资源并没有错(只是不要尝试使用 PUT)。它不是“非 REST-ful”,尤其是当您为批量操作本身创建表示时。我建议您在创建单个资源的同时创建一个索引资源,并返回一个“303 See Other”给它。然后,该索引表示将包含指向所有已创建资源的链接(如果其中任何一个资源失败,还可能包含错误信息)。

POST /categories/uploads/
[{"name": "Books"}, {"name": "Games"}]

    303 See Other
    Location: /categories/uploads/321/

(其实现在想想,201可能比303好)

GET /categories/uploads/321/

    200 OK
    Content-Type: application/json

    [{"name": "Books", "link": "/categories/Books/"},
     {"name": "Games", "error": "The 'Games' category already exists."}]

【讨论】:

  • 为什么不能直接在POST响应中返回创建的资源?
  • 因为那是 RPC,而不是 REST。返回的表示可能不会被缓存;即使您碰巧找到了一个缓存 POST 响应的缓存,它也不会缓存在标识资源的 URI 中(显然,它标识资源创建)。
  • 看起来朱利安正在看着我的肩膀;)trac.tools.ietf.org/wg/httpbis/trac/ticket/347
  • @fumanchu:我不完全同意。阅读:stackoverflow.com/a/1829913。此外,Restful Web Services 说:“实体主体:应该描述并链接到新创建的资源。如果您使用 Location 标头告诉客户端资源实际位于何处,则该资源的表示是可以接受的。”
【解决方案4】:

在您的情况下,我也会采用 /bulk 资源方式。但我建议的模式如下,据我所知,这是最自然的:使用 202 Accepted 状态代码。

批量请求的想法是不应该强迫服务器立即响应,因为这意味着客户端需要等到它的批量请求完成。

这是模式:

POST /bulk [{"name": "Books"}, {"name": "Games"}]
202 Accepted | Location: /bulk/processing/status/resourceId

GET /bulk/processing/status/resourceId
entry = "REST in peace" | completed | 0 errors | /categories/category/resourceId
entry = "Walking dead" | processing | 0 errors ->

因此,客户端将批量信息发布到服务器。服务器仅使用 202 接受它们,这不能保证响应时的处理状态。 但是服务器也提供了一个状态资源的链接。在这里,客户端可以查看每个创建的资源和处理状态。完成后,客户端可以通过给定的链接访问资源。 客户端可以识别错误情况,错误数据可能会通过 PUT 对已完成资源重新发送。

最后,我通常遵循的一个好建议是:每当您在设计中遇到无法映射到 HTTP 功能的资源时,很可能是因为缺少资源。

【讨论】:

    【解决方案5】:

    实际上,直到今天这仍然是一个热门话题,但简化一些事情,我几乎经常说每次练习都有一个适合击球手的场景。 例如: 1.如果您从帖子中收到喜欢,则不需要批量,因为以防每条评论只有一个喜欢。 2. 如果您收到最喜欢的评论,可以考虑有人查看他阅读的评论并选中他所有的收藏并发送一次。

    再次,这是基于我使用 Restful API 的经验,但目前为了多任务处理和其他事情,我和我的同事发现我们自己在大多数 MIS(管理信息系统)中一直在做大量工作我们的确是。这是因为现代网络应用程序和移动应用程序可以做很多工作并将最终结果发送到后端,这样后端只要接收到的数据不违反业务逻辑。

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      相关资源
      最近更新 更多