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):
Create a single process:
POST /resource → 202 {"monitor": "/process"} POST /resource → 409 "A request has already been accepted, retry later."
Monitor its state:
GET /process → 200 {"state": "ready"} GET /process → 200 {"state": "running", "progress": 0.75} GET /process → 200 {"state": "terminated", "product": "/product"}
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:
Create multiple processes:
POST /resource → 202 {"monitor": "/process/123"} POST /resource → 202 {"monitor": "/process/456"}
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"}
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:
- Are these two patterns the correct way to process asynchronous HTTP requests?
- 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.