0

In my application I have the concept of an Order which it is a resource that is a collection of other resources (Draws). (background: How to RESTfully support the creation of a resource which is a collection of other resources and avoiding HTTP timeouts due to DB creation?)

When a user creates an Order in the API, it will submit a JSON that looks like this:

{
    "order": {
      "draws": [
        {
            "background_color" : "rgb(0,0,0)", "font_size" : 14
        }, 
        {
           "background_color" : "rgb(255,0,0)", "font_size" : 16
        },
        ...
       ]
    }
}

Then, my application will return a tracking number to the User so he can see what is the current status for that Order, and will push that JSON to a queue so that it can be processed in the background.

However, I have a problem:

Once the Order is completed, and the User fetches the Order, I will return a list of Draws. Something like this:

      "draws": [
        {
            "background_color" : "rgb(0,0,0)", "font_size" : 14, "url" : "generated_url"
        }, 
        {
           "background_color" : "rgb(255,0,0)", "font_size" : 16, "url" : "generated_url2"
        },
        ...
       ]

My problem is:

How will the User know which Draw from the results is a draw from what he submited? Here is two solutions I have thought of:

1 - When the user submits the Order, for each of the Draws he submits a unique id, so later when those are created, he will be able to map them.

2 - When the user submits the Order, my application creates a unique id for each of the Draws. And later when the Draws are actually created in the DB, I put that unique id into the DB.

What is more reasonable, taking into account that an Order can have up to 100.000 draws.

Community
  • 1
  • 1
Hommer Smith
  • 26,772
  • 56
  • 167
  • 296

2 Answers2

1

Option #2 is similar to the solution found on page 47 of the RESTful Web Services Cookbook at Oreilly Books.

“On receiving a POST request, create a new resource, and return status code 202 (Accepted) with a representation of the new resource. The purpose of this resource is to let a client track the status of the asynchronous task. Design this resource such that its representation includes the current status of the request and related information such as a time estimate.

When the client submits a GET request to the task resource, do one of the following depending on the current status of the request:

Still processing Return response code 200 (OK) and a representation of the task resource with the current status.

On successful completion Return response code 303 (See Other) and a Location header containing a URI of a resource that shows the outcome of the task.

On task failure Return response code 200 (OK) with a representation of the task resource informing that the resource creation has failed. Clients will need to read the body of the representation to find the reason for failure.”

Excerpt From: Subbu Allamaraju. “RESTful Web Services Cookbook - Subbu Allamaraju.epub.”

user602525
  • 3,126
  • 4
  • 25
  • 40
1

Well, notice that your client is already assigning a unique ID to each of the requested draws: it's implied by their position in the draws array. So numbering the draws "1", "2", etc. would be redundant.

So long as your client and server are both able to process this array without reordering it, there is a natural mapping between draws in the request and response and I believe you already have a RESTful solution. That's assuming

  • When the client submits an order, what the server returns is a URI (not merely a tracking number) that points to the location of the corresponding new order resource.

  • When the client GETs this order representation, the response includes both the orders' processing status and the list of its associated draw resources, each of which has been assigned by the server a unique URI that points to its representation (as shown in your sample response above).

    At this point, each draw's URI becomes its unique identifier, and with the trivial mapping between arrays the client can easily update its own order representation with this information.

For efficiency (and maximal RESTfulness), when the client POSTs a new order you might have the server respond immediately with a 201 Created (or perhaps 202 Accepted) status and include the representation of the new order, including the new draw URIs, right in the response body. That way your client can both submit an order and update itself with the response in a single interaction.

  • The only problem here is that when the client submits an Order, since it takes a while to create the order, I can't respond with the ID of that new created resource, basically because it is not created yet. That's why I was thinking on responding with a tracking number. – Hommer Smith Jul 14 '14 at 16:32
  • Are you saying it takes a while to _create_ the order, or a while to _complete_ the order? I understand the draws take some time to finish but I would expect creating an order to involve little more than adding a few rows to your database. More to the point, surely in your domain model an order comes into existence when a client submits it, not when its component draws are completed (if they ever are). –  Jul 14 '14 at 20:00
  • Simon South, creating an order involves creating more than 10.000 rows in the DB (the associated draws) – Hommer Smith Jul 14 '14 at 20:04
  • Ah. Then I'd say the RESTful approach would be to return 202 Accepted on order submission along with the URI of a "job" resource the client can poll to monitor the order-creation's progress (and that will eventually return the URI of the order itself). But that doesn't answer your question about the mapping. –  Jul 14 '14 at 20:08
  • That's what I am doing :). Thanks Simon – Hommer Smith Jul 14 '14 at 20:13