Search code examples
web-servicesservicedomain-driven-designjson-rpcidempotent

Should idempotent service respond with error after first call?


I'm writing service layer for DDD app.
Services are exposed through JSON-RPC over WSS.
I'm not sure how to respond to redundant calls to service.

Some facts about the system:

  1. All requests must be completed within specific time or timeout exception occurs.
  2. If system is under heavy load it may decide to discard request (visible as timeout).
  3. If system is under heavy load some messages may expire in the queue (visible as timeout).
  4. Even if request reaches it's destination ACK may not reach user in time (visible as timeout).
  5. End user has right to re-invoke method if ACK didn't arrive in time.

No guarantees on request completion are given. Thus the need for idempotency.

Problem arises if we consider [4]+[5] implications:

  • User invokes method setFoo(Bar).
    • Entity was created but ACK didn't make it on time.
  • User receives timeout and assumes that he should try again, so he re-invokes setFoo(Bar).
  • Entity already exists -> hmm...

Question is: Should user get ACK or Error(I've already done that mate...)?


Solution

  • An idempotent operation should have the same behaviour when it is called multiple times. This suggests that the return value should be the same as well, so in the scenario you are describing above, the user should get ACK.

    Consider the alternative; if you return an error to the user, then how should the user respond? What "error handling" is appropriate?

    You can make an argument for a response of ACK(I've already done that mate...) but the part in brackets should be a purely optional informative field, not something that affects how the user processes the response.