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.

1

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.

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.
    – Maggyero
    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)?
    – Maggyero
    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". Jun 25, 2021 at 11:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.