GET/PUT/DELETE idempotent by contract; POST/PATCH not. Server stores Idempotency-Key → lock → process → replay; fingerprint body on mismatch.
Разбор
HTTP idempotency baked in: GET, PUT, DELETE, HEAD idempotent; POST, PATCH not. PUT /users/42 retry-safe (overwrite same); POST /users needs key (second user).
Server implementation (Stripe model): key + outcome ~24h.
Idempotency-Key: k arrives. Lookup.
- New → lock
k, process, store (k → status, response), return.
- Completed → replay stored response verbatim.
- In-flight duplicate →
409 Conflict / wait — lock matters.
- Optional request fingerprint — same key different body →
422.
Client dedupe — collapse concurrent in-flight into one promise (double-click). Server keys handle retry across lost response.
Итог
Timeout ≠ no-op; key once per logical action; server lock closes concurrent duplicate window.