1

Here is the pattern that I thought about for a resource accepting a single asynchronous HTTP request at a time (i.e. a request which has not yet been fulfilled when the response is sent):

  1. Create a single process:

    POST /resource → 202 {"monitor": "/process"}
    POST /resource → 409 "A request has already been accepted, retry later."
    
  2. Monitor its state:

    GET /process → 200 {"state": "ready"}
    GET /process → 200 {"state": "running", "progress": 0.75}
    GET /process → 200 {"state": "terminated", "product": "/product"}
    
  3. Retrieve its product:

    GET /product → 200 foo
    

The product is optional since it depends on the nature of the process (e.g. a video encoding process has a product while a machine shutdown process does not) and only makes sense for the POST method.

And here is the pattern that I thought about for a resource accepting multiple asynchronous HTTP requests at a time:

  1. Create multiple processes:

    POST /resource → 202 {"monitor": "/process/123"}
    POST /resource → 202 {"monitor": "/process/456"}
    
  2. Monitor their states:

    GET /process/123 → 200 {"state": "ready"}
    GET /process/456 → 200 {"state": "ready"}
    GET /process/123 → 200 {"state": "running", "progress": 0.75}
    GET /process/456 → 200 {"state": "running", "progress": 0.50}
    GET /process/123 → 200 {"state": "terminated", "product": "/product/123"}
    GET /process/456 → 200 {"state": "terminated", "product": "/product/456"}
    
  3. Retrieve their products:

    GET /product/123 → 200 foo
    GET /product/456 → 200 bar
    

Again the product is optional since it depends on the nature of the process and only makes sense for the POST method.

Now here are my questions:

  1. Are these two patterns the correct way to process asynchronous HTTP requests?
  2. Can asynchronous HTTP requests be idempotent?

A definition of idempotence is given in RFC 7231, § 4.2.2. ‘Idempotent Methods’:

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.

So it seems to me that asynchronous HTTP requests cannot be idempotent with the multiple asynchronous HTTP requests pattern, since part of their intended effect is to always create resources on the server (e.g. /process/123 and /product/123). However it seems to me that asynchronous HTTP requests can be idempotent with the single asynchronous HTTP request pattern, depending on their intended effect, since they do not have this systematic resource creation as part of their intended effect.

asked Jun 24, 2021 at 20:58
1
  • This seems almost a duplicate of softwareengineering.stackexchange.com/questions/429179/…. In that case it's restarting the server. In this case it's starting a 'process'. Did you resolve that question? If so, why doesn't the answer apply here? Commented Jun 25, 2021 at 0:23

1 Answer 1

3

Are these two patterns the correct way to process asynchronous HTTP requests?

They are a correct way to process asynchronous HTTP requests.

The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.

Notice that "ought to" is not of the requirements levels described by RFC 2119.

Can asynchronous HTTP requests be idempotent?

Yes.

PUT /announcements HTTP/1.1
Content-Type: text/plain
This is tomorrow's announcement
HTTP/1.1 202 Accepted
Content-Type: text/plain
Maybe I'll do that at midnight.

So it seems to me that asynchronous HTTP requests cannot be idempotent with the pattern accepting multiple asynchronous HTTP requests at a time, since part of their intended effect is to always create resources on the server

Not all asynchronous HTTP requests create unique resources. Upserting or deleting resources can be done asynchronously too.

Also, be aware that the "idempotent" constraint describes the semantics of the request, not the implementation (see Fielding 2002). The semantics of a PUT or DELETE request don't depend on whether the server happens to choose to act on the request at once or accept it for processing later.

answered Jun 25, 2021 at 2:21
3
  • Very helpful, thanks! ‘The semantics of a PUT or DELETE request don't depend on whether the server happens to choose to act on the request at once or accept it for processing later.’ I think you nailed it. This means that the creation of the process resource, even when it is unique per request like in the second pattern (e.g. /process/123), is actually a side effect, not an intended effect like I thought. So yes, both patterns allow idempotent asynchronous requests. Commented Jun 25, 2021 at 11:05
  • ‘Notice that "ought to" is of the requirements levels described by RFC 2119.’ You are right, I included the request’s status monitor but forgot to include the request’s current status in the bodies of my 202 responses. Haven’t you forgot it too by the way (‘Maybe I'll do that at midnight.’ looks like an embedded status monitor without a current status)? Commented Jun 25, 2021 at 11:10
  • No, that means that I forgot a very important "not" in the text of my answer. If the standards authors meant SHOULD (in the 2119 sense) then they SHOULD have used that spelling, not "ought to". Commented Jun 25, 2021 at 11:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.