How to RESTfully support the creation of a resource which is a collection of other resources and avoiding HTTP timeouts due to DB creation?

独自空忆成欢 提交于 2019-12-13 01:03:07

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/24660479/how-to-restfully-support-the-creation-of-a-resource-which-is-a-collection-of-oth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!