Separate the response from the effect

Consider a job-submission service. A client sends a request, the server creates the job, and the connection drops before the response reaches the client. The client sees a timeout. The server may already have completed the requested action. Repeating the request without a way to recognize it can create another job.

HTTP describes an idempotent method as one whose intended server effect is the same after repeated identical requests as after one request. PUT, DELETE, and safe methods have that property in the protocol. A generic POST does not acquire it merely because a client adds retry logic. Consult the service's documented semantics before automatically replaying an operation.

Design the duplicate path explicitly

For an application that supports an idempotency key, define the scope of that key, how long it is retained, and what happens when a caller reuses it with different content. A useful design associates the key with the authenticated caller and a fingerprint of the intended operation. A repeated key with different content should produce a clear conflict rather than silently reuse an unrelated result.

The important implementation detail is concurrency. Two identical submissions can arrive at nearly the same time. A read-then-write check without coordination can let both through. The persistence design must ensure that only one operation is accepted for the key and that its state can be retrieved after a process interruption. A unique constraint can help, but it does not by itself make an external side effect transactional.

Test uncertain outcomes

Test the point where work has completed but the response is lost. Then replay the request and verify the actual number of jobs or other side effects. Also test concurrent duplicates, expiration of stored keys, and a crash between saving state and contacting a downstream service.

Retries should have limits and delays appropriate to the documented service. Backoff can reduce load, but it does not solve duplicate execution. A sound retry design gives the caller a way to discover what happened and gives the system a way to recognize work it has already accepted.

Explore the API Contract Lab ↗