Idempotency and Optimistic Updates for Financial Mutations
Context
Financial operations like transfers must never be duplicated and should provide instant feedback to users.
Decision
- Client-generated idempotency key (
crypto.randomUUID()) sent with everytransferFundsmutation. - Optimistic update pattern using React Query’s
onMutate,onError,onSettled. - Retry disabled for mutations (
retry: false) – network failures require explicit user retry, not automatic ones.
Alternatives Considered
- Server-generated idempotency keys – adds a round-trip, not suitable for instant feedback.
- Apollo Client’s optimistic response – tightly coupled to GraphQL; React Query’s approach is backend-agnostic and gives explicit cache control.
Optimistic update lifecycle
Optimistic updates give instant feedback. The snapshot ensures rollback is always available. onSettled always refetches: the server's answer is the final truth.
Consequences
- Frontend must handle rollback logic carefully; snapshot integrity is critical.
- Backend must store idempotency keys with a TTL.