Long running ReST requests and status endpoints

This is a very brief post about how to handle long-running requests in your ReST API. Sometimes, requests can't be handled immediately and your API should return information to the caller so that they can check the progress.

If you have a ReST API endpoint that takes a long time to process requests, it is common practice to return a 202 Accepted response and include a header with a link to an endpoint that gives the status of the operation.

For example, a caller POSTs this request:

POST https://api.yourservice.com/bigthing HTTP/1.1
Accept: application/json

{
"field": "value"
}

... and the server responds with:

HTTP/1.1 202 Accepted
Operation-Location: https://api.yourservice.com/operations/123

Now your callers can call that polling endpoint to check the status.

But what return code should https://api.yourservice.com/operations/123 return? Should it return a 200 OK with a resource describing the status of the job, or should it return another 202 Accepted if the job is still running and then a 200 OK (or 201 Created)?

There is some some conflicting advice around this. Some of it says that the polling endpoint should return 202 Accepted until the resource is ready. One such page is on the Azure architecture patterns site, named: Asynchronous Request-Reply pattern. It has this diagram:

In my opinion, this is the wrong advice (I submitted a pull request to correct it).

👌 Update January 2022
The PR was accepted and that document has now been updated.

The HTTP return code should be for the resource that is being returned, and not for some resource that was previously requested. So, the resource being asked for is 'the status of the original request', and what's being returned is a resource describing 'the status of the original request'. A 202 Accepted is saying 'I accept your request for the status of the original request'

The HyperText Transfer Protocol (HTTP) 202 Accepted response status code indicates that the request has been accepted for processing, but the processing has not been completed (#)

The Microsoft API guidelines page, in section 13.2.7 has the right advice. It says that the polling endpoint should return a 200 OK. For the simple example above, the caller calls the polling endpoint:

GET https://api.yourservice.com/v1.0/operations/123
Accept: application/json

... and the polling endpoint returns

HTTP/1.1 200 OK
Retry-After: 30

{
"createdDateTime": "2021-12-24T09-00-00.0Z",
"status": "running"
}

... the client calls it again after 30 seconds, and gets:

HTTP/1.1 200 OK
Content-Type: application/json

{
"createdDateTime": "2021-12-24T09-00-30.0Z",
"lastActionDateTime": "2021-12-24T09-00-00.0Z",
"status": "succeeded",
"resourceLocation": "https://api.yourservice.com/bigthings/42"
}

In summary, long running operations in a ReST API should provide polling endpoints. The polling endpoints are no different to other endpoints and should follow the same standards used for any other request for a resource. Be aware that some online articles can be confusing or contradictory, particularly when they deviate from the ReST guidelines. Following the ReST guidelines ensures a consistent experience for your users and they'll thank you for it (only joking, they just won't moan about it being wrong!)

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.

Leave a comment

Comments are moderated, so there may be a short delays before you see it.

Published