如何以REST方式支持创建一个资源,该资源是其他资源的集合,并避免因DB创建而导致HTTP超时?[英] How to RESTfully support the creation of a resource which is a collection of other resources and avoiding HTTP timeouts due to DB creation?

本文是小编为大家收集整理的关于如何以REST方式支持创建一个资源,该资源是其他资源的集合,并避免因DB创建而导致HTTP超时?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在我的应用程序中,我有一个绘图的概念,并且绘制必须始终包含在订单中.

绘制有一组属性:background_color, font_size, ...

引用着名的休息论文:

可以命名的任何信息都可以是资源:文档或 图像,一个时间服务(例如,"今天的天气在洛杉矶"),一个 收集其他资源,非虚拟对象(例如一个人), 等等.

所以,我在这里的其他资源的收集将是一个订单.订单是一组绘图(通常超过成千上万).我想让用户用几个绘制创建一个订单,这是我的第一个方法:

{
    "order": {
      "background_color" : "rgb(255,255,255)", "font_size" : 10,
      "draws_attributes": [{
            "background_color" : "rgb(0,0,0)", "font_size" : 14
        }, {
           "other_attribute" : "value",
        },
       ]
       }
}

对此的响应将如下所示:

"order": {
          "id" : 30,
          "draws": [{
                "id" : 4
            }, {
               "id" : 5
            },
           ]
           }
    }
所以用户会知道DB中已创建哪些资源.但是,当请求中有许多绘制时,由于所有这些绘制都插入DB中,因此响应需要一段时间.想象一下,如果订单有10.000次绘制,请执行10.000插入.

因为我需要向用户提供刚刚创建的绘制的ID(顺便说一下,创建但未完成,因为当处理订单时,我们实际上建立了一些图像操作库),所以他们可以以后获取它们,我没有看到如何以宁静的方式处理这个,避免使HTTP请求花费大量时间,但同时给用户提供某种ID的绘制,所以他们可以提取它们稍后.

如何处理这种情况?

推荐答案

接受请求批发,队列处理,返回表示请求状态的状态URL.当请求完成处理时,呈现表示请求结果的URL.然后,民意调查.

POST /submitOrder

301
Location: http://host.com/orderstatus/1234

GET /orderstatus/1234

200
{ status:"PROCESSING", msg: "Request still processing"}

...

GET /orderstaus/1234

200
{ status:"COMPLETED", msg: "Request completed", rel="http://host.com/orderresults/3456" }

addenda:

好吧,有一些选择.

1)它们可以等待结果处理并在完成后获取ID,就像现在一样.与我所建议的差异是网络连接的状态没有与交易的成功或失败相关联.

2)您可以在击中数据库之前预先分配订单ID,并将那些返回调用者.但请注意,这些资源尚不存在(并且在处理完成之前,它们不会).

3)加快系统到超时根本不是问题的位置.

其他推荐答案

我认为您的暴露粒度太精细 - 用户是否需要单独修改每个Draw?如果没有,则呈现表示Order的文档,并且包含自然地Draw s.

您是否需要根据与Order无关的特定条件查询从数据库中的特定Draw S?如果不是,则表示所有Draw作为单个blob,它是表示Order的行的一部分.

本文地址:https://www.itbaoku.cn/post/1937861.html

问题描述

In my application I have the concept of a Draw, and that Draw has to always be contained within an Order.

A Draw has a set of attributes: background_color, font_size, ...

Quoting the famous REST thesis:

Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on.

So, my collection of other resources here would be an Order. An Order is a set of Draws (usually more than thousands). I want to let the User create an Order with several Draws, and here is my first approach:

{
    "order": {
      "background_color" : "rgb(255,255,255)", "font_size" : 10,
      "draws_attributes": [{
            "background_color" : "rgb(0,0,0)", "font_size" : 14
        }, {
           "other_attribute" : "value",
        },
       ]
       }
}

A response to this would look like this:

"order": {
          "id" : 30,
          "draws": [{
                "id" : 4
            }, {
               "id" : 5
            },
           ]
           }
    }

So the User would know which resources have been created in the DB. However, when there are many draws in the request, since all those draws are inserted in the DB, the response takes a while. Imagine doing 10.000 inserts if an Order has 10.000 draws.

Since I need to give the User the ID of the draws that were just created (by the way, created but not finished, because when the Order is processed we actually build the Draw with some image manipulation libraries), so they can fetch them later, I fail to see how to deal with this in a RESTful way, avoiding to make the HTTP request take a lot time, but at the same time giving the User some kind of Ids for the draws, so they can fetch them later.

How do you deal with this kind of situations?

推荐答案

Accept the request wholesale, queue the processing, return a status URL that represents the state of the request. When the request is finished processing, present a url that represents the results of the request. Then, poll.

POST /submitOrder

301
Location: http://host.com/orderstatus/1234

GET /orderstatus/1234

200
{ status:"PROCESSING", msg: "Request still processing"}

...

GET /orderstaus/1234

200
{ status:"COMPLETED", msg: "Request completed", rel="http://host.com/orderresults/3456" }

Addenda:

Well, there's a few options.

1) They can wait for the result to process and get the IDs when it's done, just like now. The difference with what I suggested is that the state of the network connection is not tied to the success or failure of the transaction.

2) You can pre-assign the order ids before hitting the database, and return those to the caller. But be aware that those resources do not exist yet (and they won't until the processing is completed).

3) Speed up your system to where the timeout is simply not an issue.

其他推荐答案

I think your exposed granularity is too fine - does the user need to be able to modify each Draw separately? If not, then present a document that represents an Order, and that contains naturally the Draws.

Will you need to query specific Draws from the database based on specific criteria that are unrelated to the Order? If not, then represent all the Draws as a single blob that is part of a row that represents the Order.