Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is HTTP 303 considered harmful for asynchronous operations?

While researching RESTful APIs for asynchronous operations I ran across the following design pattern:

POST uri:longOperation returns:

  • HTTP 202
  • Location: uri:pendingOperation

GET uri:pendingOperation returns:

  • If operation is running
    • Return a progress report.
  • If operation is complete
    • HTTP 303
    • Location: uri:operationResponse

GET uri:operationResponse

  • The response of the asynchronous operation

I find the last step questionable. Consider what happens if the asynchronous operation completes with an error code that doesn't make sense for HTTP GET, such as HTTP 409 ("Conflict").

  1. Isn't HTTP 303 required to point to the response associated with uri:pendingOperation as opposed to uri:operationResponse?
  2. Is using HTTP 303 in this way considered harmful? If not, why?
  3. Is this the best we can do, or is there a better way?
like image 783
Gili Avatar asked Dec 13 '12 19:12

Gili


1 Answers

Isn't HTTP 303 required to point to the response associated with uri:pendingOperation as opposed to uri:operationResponse?

The spec doesn't explicitly say it is required, but I tend to agree with you.

Is using HTTP 303 in this way considered harmful? If not, why?

I think you lose capabilities by doing a 303. While it is "nice" to auto-redirect when done, it makes it so that you don't have an opportunity to provide meta data around the results, that can be leveraged for reporting etc... Also many clients don't auto follow 303, so the client may need to do work to follow the 303 Location header anyways.

Is this the best we can do, or is there a better way?

I tend to recommend having the GET uri:pendingOperation return 200 with a status resource always with a reference to the output when it is "complete". Something like

When Incomplete

{
    "status" : "PENDING"
}

When Error

{
    "status" : "COMPLETE"
    "errors" : [
       {
          "typeId" : "OPERATION_TIMEOUT",
          "description" : " "The request was unable to complete because the systems are unresponsive".
       }
    ]
}

When Successful

{
    "status" : "COMPLETE"
    "links" : {
       "result" : {
          "href" : "http://api.example.com/finished-resource/1234",
       }
    ]
}

like image 109
Daniel Roop Avatar answered Oct 14 '22 02:10

Daniel Roop