4

I need help creating a RESTful design for an application with a progress bar.

Imagine an application where one of the resources takes a long time (1+ minutes) to respond to HTTP GET (in my case, I'm scanning the network for devices). I'd like clients to display a progress bar indicating how long the GET operation will take but in order for this to work the server needs to provide them with a time estimate for the operation.

Given a slow operation:

HTTP GET /devices

What's a RESTful way of providing a time estimate for it? I don't think I can use:

HTTP HEAD /devices

because HEAD is supposed to return the same values as GET minus the body which (I think) means I'll have to run the very same long operation I'm trying to avoid. Any ideas?

Gili
  • 86,244
  • 97
  • 390
  • 689

2 Answers2

10

On second thought, I think I will opt for an incremental response. According to RESTful Web Services asynchronous operations are best represented in terms of HTTP 202.

  1. Client sends HTTP POST /devices
  2. Server responds HTTP 202 Accepted. Location: /queues/32194532
  3. Quoting the book:

    The asynchronous operation is now in progress, and the client can make GET requests to that URI to see how it’s going— that is, to get the current state of the “job” resource. Once the operation is complete, any results will become available as a representation of this resource. Once the client is done reading the results it can DELETE the job resource. The client may even be able to cancel the operation by DELETEing its job prematurely.

  4. Quoting https://stackoverflow.com/a/5081246/14731: The job should return 200 OK when the requested process is still pending. The Response should describe the pending status of the process.
  5. Quoting https://stackoverflow.com/a/5081246/14731: The job should return 201 Created when the processing has been completed. The Response in case of GET/PUT/POST should contain the Location to the requested/created/updated resource.
  6. Quoting the book:

    There’s one wrinkle. Because every request to start an asynchronous operation makes the server create a new resource (if only a transient one), such requests are neither safe nor idempotent. This means you can’t spawn asynchronous operations with GET, DELETE, or (usually) PUT. The only HTTP method you can use and still respect the uniform interface is POST.

Community
  • 1
  • 1
Gili
  • 86,244
  • 97
  • 390
  • 689
  • This seems like a better way for the client to be able to check on the status as it wills (of course, the server has to update that resource in some way. The first response to this question probably should be a POST as well. ( http://stackoverflow.com/a/8388956/525 ) – pc1oad1etter Dec 05 '11 at 18:19
2

Maybe just create a separate "progress" resource?

GET /progress/foo
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • My reason for not doing this would be, "because it's not a resource - it's fake". – John Saunders Dec 05 '11 at 17:26
  • 1
    Fake? so when you GET /person/1 is that a 'real' person? – pc1oad1etter Dec 05 '11 at 18:04
  • Agreed - you can make this a separate resource. For example, if your resource with information about the cost of the query were located at /devices/queryinfo then.... You can add a linkheader in /devices pointing /devices/queryinfo . Then, clients have the option of getting the link from the HEAD result, and check out how costly the action may be before taking it. – pc1oad1etter Dec 05 '11 at 18:15