Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring HTTP replay key: two requests, one modeled reservation

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A stable replay key lets a remote handler identify two attempts as one logical command when it enforces that key.

Download Spring source kit

Repeat the same command

After the first timed-out POST, RestClientBoundaryTest releases the delayed response and sends another POST with the same Idempotency-Key. The local server sees two HTTP requests, returns reservation-2048 and records one write. The test checks both counters and the stored key. This is a server-enforced behavior; RestClient does not provide deduplication by itself.

The key belongs to the normalized command and tenant. The tenant-scoping lesson explains why the same opaque text used by a different tenant must not select another tenant’s result. A key reused for changed request contents should be rejected rather than returning the first response.

Draw the boundary around the model

The loopback handler uses a concurrent in-memory set, not a database transaction. It has no TTL, payload hash, failure-after-reservation recovery or protection across two server replicas. The test also sends attempts sequentially; it does not race two first requests against the same key.

A production remote service must store the key and result atomically with the mutation, specify retention, and let a caller retrieve the prior result after an uncertain response. The timeout trace explains why this is necessary.

Checked source

Java
// The second POST reuses tenant-east-receipt-2048.
assertEquals(2, requests.get());
assertEquals(1, writes.get());
assertEquals(Set.of("tenant-east-receipt-2048"), committedKeys);

Verification boundary

RestClientBoundaryTest.aTimedOutWriteMayHaveCommittedBeforeTheCallerRetries.

Costs and limits

Sequential local requests and one in-memory remote process are checked. Durable replay, TTL, changed payloads and concurrent first-use races remain open.

Common Mistakes

  • Do not call a header a deduplication guarantee unless the server enforces it.
  • Do not reuse one key for a changed command.
  • Do not claim a sequential set test proves a distributed race.

Read next

Spring HTTP timeout after POST: the write may already exist, Spring POST idempotency keys: bind replay to tenant and command, Spring POST idempotency keys: replay the same receipt result, Spring HTTP retries: only replay a command with a defined identity.

spring
restclient
http
Storage details