While researching RESTful APIs for asynchronous operations I ran across the following design pattern:
POST uri:longOperation
returns:
GET uri:pendingOperation
returns:
GET uri:operationResponse
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")
.
HTTP 303
required to point to the response associated with uri:pendingOperation as opposed to uri:operationResponse?HTTP 303
in this way considered harmful? If not, why?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",
}
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With